Minecraft-Ships / ShipsForCore

The main code to run Ships
https://minecraft-ships.github.io/ShipsForCore/
BSD 2-Clause "Simplified" License
7 stars 6 forks source link

Issue after collide #67

Open ThatPerkel opened 2 years ago

ThatPerkel commented 2 years ago

Hello, we are getting this error whenever we try to change move speed. Then the Ship is locked and Ships says "Ships sign is already moving ship". Could you somehow fix this, as it makes this plugin unusable?

[21:18:40 ERROR]: [Ships] [STDERR] Failed to know what to do: EventListener caused exception from org.ships.event.listener.CoreEventListener.onPlayerInteractWithBlock(AsPlayer arg0)
[21:18:40 WARN]: java.lang.IllegalStateException: Duplicate key Vector3{X: 148, Y: 65, Z: -5847} (attempted merging values org.ships.vessel.common.types.typical.marsship.Marsship@7daca2ae and org.ships.vessel.common.types.typical.marsship.Marsship@13b465af)
[21:18:40 WARN]: at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:135)
[21:18:40 WARN]: at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:182)
[21:18:40 WARN]: at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
[21:18:40 WARN]: at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1694)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
[21:18:40 WARN]: at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
[21:18:40 WARN]: at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.vessel.common.loader.ShipsOvertimeBlockFinder.loadOvertime(ShipsOvertimeBlockFinder.java:32)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.vessel.sign.MoveSign.onPrimaryClick(MoveSign.java:85)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.event.listener.CoreEventListener.lambda$onPlayerInteractWithBlock$11(CoreEventListener.java:199)
[21:18:40 WARN]: at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
[21:18:40 WARN]: at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
[21:18:40 WARN]: at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1694)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
[21:18:40 WARN]: at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
[21:18:40 WARN]: at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
[21:18:40 WARN]: at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
[21:18:40 WARN]: at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.event.listener.CoreEventListener.onPlayerInteractWithBlock(CoreEventListener.java:192)
[21:18:40 WARN]: at jdk.internal.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)
[21:18:40 WARN]: at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[21:18:40 WARN]: at java.base/java.lang.reflect.Method.invoke(Method.java:567)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.implementation.bukkit.event.BEventLaunch.run(BEventLaunch.java:41)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.implementation.bukkit.event.BukkitListener.lambda$call$2(BukkitListener.java:229)
[21:18:40 WARN]: at java.base/java.lang.Iterable.forEach(Iterable.java:75)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.implementation.bukkit.event.BukkitListener.call(BukkitListener.java:229)
[21:18:40 WARN]: at ShipsBukkit.jar//org.ships.implementation.bukkit.event.BukkitListener.onPlayerInteractWithBlockEvent(BukkitListener.java:178)
[21:18:40 WARN]: at com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor.execute(StaticMethodHandleEventExecutor.java:38)
[21:18:40 WARN]: at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80)
[21:18:40 WARN]: at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70)
[21:18:40 WARN]: at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:630)
[21:18:40 WARN]: at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:543)
[21:18:40 WARN]: at net.minecraft.server.level.PlayerInteractManager.a(PlayerInteractManager.java:542)
[21:18:40 WARN]: at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1810)
[21:18:40 WARN]: at net.minecraft.network.protocol.game.PacketPlayInUseItem.a(PacketPlayInUseItem.java:33)
[21:18:40 WARN]: at net.minecraft.network.protocol.game.PacketPlayInUseItem.a(PacketPlayInUseItem.java:9)
[21:18:40 WARN]: at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$ensureRunningOnSameThread$1(PlayerConnectionUtils.java:56)
[21:18:40 WARN]: at net.minecraft.server.TickTask.run(TickTask.java:18)
[21:18:40 WARN]: at net.minecraft.util.thread.IAsyncTaskHandler.executeTask(IAsyncTaskHandler.java:149)
[21:18:40 WARN]: at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.executeTask(IAsyncTaskHandlerReentrant.java:23)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:1418)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:192)
[21:18:40 WARN]: at net.minecraft.util.thread.IAsyncTaskHandler.executeNext(IAsyncTaskHandler.java:122)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1396)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.executeNext(MinecraftServer.java:1389)
[21:18:40 WARN]: at net.minecraft.util.thread.IAsyncTaskHandler.awaitTasks(IAsyncTaskHandler.java:132)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.sleepForTick(MinecraftServer.java:1367)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1278)
[21:18:40 WARN]: at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319)
[21:18:40 WARN]: at java.base/java.lang.Thread.run(Thread.java:831)

Using Paper-297 (MC: 1.17.1).

mosemister commented 2 years ago

Thats a new one for me.

Whats happened is you have two or more ships loaded in the exact same position. No idea how you managed to do that? Worldedit the ship out?

A fix would be to destory the ships sign, reload the plugin / reset the server, then put the sign back on.

Another option is to find out all ships that have the main location in the following position

X: 148 Y: 65 Z: -5847

This issue is a odd one that cant be patched there, however if I know how it occured, then I can fix that

ThatPerkel commented 2 years ago

Okay, found it... Somebody on our server crashed three vessels together. It would be great if ships would be better at managing collisions between vessels (or generally, if you want to tow one vessel with another).

mosemister commented 2 years ago

Collision is a bit of a difficult one to handle as Ships can only have a single ships sign on a ship. So when two ships collide, it can cause issues, hence why Ships does a lot to prevent collisions.

The obvious answer to fix it is after a ship move, it rechecks its structure, if another ships sign is detected then destroy it. The issue there is Ships as a whole would use a lot more resources for checking that.

I could probably make a ships addon for it though.

If you have any other ideas on how to handle ships colliding then that would be great

ThatPerkel commented 2 years ago

Your solution seems fine. I would just instead of sign destruction just "desync" it and wrote it to chat, so when you detach the vessels, you could just right-click the Ships sign and the vessel would be ready to go. I'm pretty sure this was the way it was working in the Ships 3/Ships 4 era - we were doing a lot of collisions and attaching/detaching at that time.

mosemister commented 2 years ago

The issue with "desyncing" it is you can only desync it in memory, if you reboot the server, it will attempt to load the ship and most likely crash.

The reason it worked in 1-4 is back in those days is ships didnt use memory at all and it wouldnt have load issues as if there was a issue when loading, it just skipped without warning

ThatPerkel commented 2 years ago

So, the next solution that comes to my mind is... This issue happens only when you auto-detect construction on move. So, let's add a condition to the detection algorithm, if it finds out it's construction is colliding with other Ship, simply cancel the checking and try to move the Ship (and also notify the driver).