maptool
maptool copied to clipboard
[Bug]: Spamming spacebar while dragging a token can create invalid paths or generate CMEs
Describe the Bug
If waypoints are being set quickly during a token drag, it is possible for the path to have multiple branches, for waypoints to not match the path, or for CMEs to the thrown and shown to the user. Any of these symptoms seem to be achievable without the others or in conjunction with the others.
Waypoint issues include missing waypoints and repeated waypoints when they should be unique.
To Reproduce
- Enable pathfinding (not sure if this is required).
- Drag a token around while spamming spacebar to set waypoints all over the place.
- Eventually you should find paths with strange shapes, or see a CME.
Expected Behaviour
Pathfinding should produce true paths (no branches) and should include all waypoints necessary to produce the path. Waypoints should not be duplicated within a path. Errors should not be produced.
Screenshots
Here is an example problem path found in this campaign:
There's a few weird things going on with this case. The path distances show a branch in the path when stepping out of cell (17, 8) (the step from distance=185 to distance=190). The actual list of cells steps normally all the way to the left at (-2, 8), but then jumps back to to (18, 8) (where distance = 180) to continue down the second branch. A waypoint was set at (-2, 8), but that waypoint was either lost or toggled back off (I'm not sure). Another oddity is that waypoint (14, 6) is repeated at two different points in the path.
MapTool Info
1.13.2, develop
Desktop
Linux 21.2
Additional Context
Here is an example CME as generated on latest develop (efc31d943):
java.util.ConcurrentModificationException: null at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1095) ~[?:?] at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1049) ~[?:?] at net.rptools.maptool.client.walker.AbstractZoneWalker.removeWaypoint(AbstractZoneWalker.java:182) ~[main/:?] at net.rptools.maptool.client.walker.AbstractZoneWalker.toggleWaypoint(AbstractZoneWalker.java:203) ~[main/:?] at net.rptools.maptool.client.ui.zone.renderer.SelectionSet.toggleWaypoint(SelectionSet.java:169) ~[main/:?] at net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.toggleMoveSelectionSetWaypoint(ZoneRenderer.java:358) ~[main/:?] at net.rptools.maptool.client.tool.PointerTool.setWaypoint(PointerTool.java:1454) ~[main/:?] at net.rptools.maptool.client.tool.PointerTool$PointerActionListener.actionPerformed(PointerTool.java:1475) ~[main/:?] at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1810) ~[?:?] at java.desktop/javax.swing.JComponent.processKeyBinding(JComponent.java:2956) ~[?:?] at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:3018) ~[?:?] at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2918) ~[?:?] at java.desktop/java.awt.Component.processEvent(Component.java:6398) ~[?:?] at java.desktop/java.awt.Container.processEvent(Container.java:2266) ~[?:?] at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996) ~[?:?] at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) ~[?:?] at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828) ~[?:?] at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952) ~[?:?] at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883) ~[?:?] at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1146) ~[?:?] at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020) ~[?:?] at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848) ~[?:?] at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4877) ~[?:?] at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) ~[?:?] at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780) ~[?:?] at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828) ~[?:?] at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775) ~[?:?] at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) ~[?:?] at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) ~[?:?] at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) ~[?:?] at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87) ~[?:?] at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98) ~[?:?] at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747) ~[?:?] at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?] at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) ~[?:?] at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87) ~[?:?] at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744) ~[?:?] at net.rptools.maptool.client.swing.MapToolEventQueue.dispatchEvent(MapToolEventQueue.java:54) [main/:?] at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?] at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?] at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?] at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?] at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?] at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]
Something else that may be related is that we draw waypoints wherever a token is dragged back over its path, e.g., by dragging it right, setting a waypoint, then dragging back left:
The waypoint is only visible if the token has some transparency.