MegaMek / megamek

MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight using giant robots, tanks, and/or infantry on a hex-based map.
http://www.megamek.org
GNU General Public License v2.0
296 stars 286 forks source link

[0.50.01-2024-10-21] MM from MHQ spams exceptions when saving, produces unreadable saves #6136

Open WeaverThree opened 3 hours ago

WeaverThree commented 3 hours ago

Prerequisites and Pre-Issue Checklist

Severity *

Critical (Game-breaking/Crash): The game crashes or a core feature (like saving, loading, or network connection) is completely unusable.

Brief Description *

When I'm playing a MM match started from MHQ, every time it goes to save I get an exception like this the first time:

21:19:37,411 ERROR [megamek.server.GameManagerSaveHelper] {Packet Pump}
megamek.server.GameManagerSaveHelper.saveGame(GameManagerSaveHelper.java:80) - Unable to save file: savegames/autosave.sav
java.lang.NullPointerException: Cannot invoke "Object.toString()" because the return value of "java.util.Map$Entry.getValue()" is null
    at com.thoughtworks.xstream.core.DefaultConverterLookup.lookupConverterForType(DefaultConverterLookup.java:96)
    at com.thoughtworks.xstream.XStream$1.lookupConverterForType(XStream.java:478)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:49)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:270)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:174)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:262)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:90)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:270)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:174)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:262)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:90)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:87)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeBareItem(AbstractCollectionConverter.java:94)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:66)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeCompleteItem(AbstractCollectionConverter.java:81)
    at com.thoughtworks.xstream.converters.collections.MapConverter.marshal(MapConverter.java:80)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:270)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:174)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:262)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:90)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
    at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:83)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
    at com.thoughtworks.xstream.XStream.marshal(XStream.java:1303)
    at com.thoughtworks.xstream.XStream.marshal(XStream.java:1292)
    at com.thoughtworks.xstream.XStream.toXML(XStream.java:1265)
    at megamek.server.GameManagerSaveHelper.saveGame(GameManagerSaveHelper.java:77)
    at megamek.server.AbstractGameManager.saveGame(AbstractGameManager.java:214)
    at megamek.server.AbstractGameManager.autoSave(AbstractGameManager.java:209)
    at megamek.server.totalwarfare.TWPhasePreparationManager.managePhase(TWPhasePreparationManager.java:227)
    at megamek.server.totalwarfare.TWGameManager.prepareForCurrentPhase(TWGameManager.java:1741)
    at megamek.server.AbstractGameManager.changePhase(AbstractGameManager.java:109)
    at megamek.server.totalwarfare.TWPhaseEndManager.managePhase(TWPhaseEndManager.java:73)
    at megamek.server.totalwarfare.TWGameManager.endCurrentPhase(TWGameManager.java:1897)
    at megamek.server.AbstractGameManager.changePhase(AbstractGameManager.java:112)
    at megamek.server.totalwarfare.TWPhaseEndManager.managePhase(TWPhaseEndManager.java:54)
    at megamek.server.totalwarfare.TWGameManager.endCurrentPhase(TWGameManager.java:1897)
    at megamek.server.totalwarfare.TWGameManager.changeToNextTurn(TWGameManager.java:2039)
    at megamek.server.totalwarfare.TWGameManager.executeCurrentPhase(TWGameManager.java:1779)
    at megamek.server.AbstractGameManager.changePhase(AbstractGameManager.java:116)
    at megamek.server.totalwarfare.TWPhaseEndManager.managePhase(TWPhaseEndManager.java:45)
    at megamek.server.totalwarfare.TWGameManager.endCurrentPhase(TWGameManager.java:1897)
    at megamek.server.totalwarfare.TWGameManager.checkReady(TWGameManager.java:1282)
    at megamek.server.AbstractGameManager.handlePacket(AbstractGameManager.java:63)
    at megamek.server.totalwarfare.TWGameManager.handlePacket(TWGameManager.java:588)
    at megamek.server.Server.handle(Server.java:1330)
    at megamek.server.Server$PacketPump.run(Server.java:138)
    at java.base/java.lang.Thread.run(Thread.java:840)

And one like this every subsequent time.

11:28:12,173 ERROR [megamek.client.ui.swing.MegaMekGUI] {AWT-EventQueue-0}
megamek.client.ui.swing.MegaMekGUI.loadGame(MegaMekGUI.java:628) - Error: unable to load game file "/home/weaver/.local/MekHQ-0.50.01-SNAPSHOT-2024-10-21/savegames/Round-11-autosave_2024-10-22_10-53-52.sav.gz"
org.xml.sax.SAXParseException; lineNumber: 9089; columnNumber: 48; XML document structures must start and end within the same entity.
    at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:262)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342)
    at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122)
    at megamek.client.ui.swing.MegaMekGUI.loadGame(MegaMekGUI.java:602)
    at megamek.client.ui.swing.MegaMekGUI.lambda$new$0(MegaMekGUI.java:1051)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at megamek.client.ui.swing.widget.MegaMekButton.processMouseEvent(MegaMekButton.java:246)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    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:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    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:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
    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)

The save file is then unusable, giving an exception like this when I try to load it.

11:28:12,173 ERROR [megamek.client.ui.swing.MegaMekGUI] {AWT-EventQueue-0}
megamek.client.ui.swing.MegaMekGUI.loadGame(MegaMekGUI.java:628) - Error: unable to load game file "/home/weaver/.local/MekHQ-0.50.01-SNAPSHOT-2024-10-21/savegames/Round-11-autosave_2024-10-22_10-53-52.sav.gz"
org.xml.sax.SAXParseException; lineNumber: 9089; columnNumber: 48; XML document structures must start and end within the same entity.
    at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:262)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342)
    at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122)
    at megamek.client.ui.swing.MegaMekGUI.loadGame(MegaMekGUI.java:602)
    at megamek.client.ui.swing.MegaMekGUI.lambda$new$0(MegaMekGUI.java:1051)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at megamek.client.ui.swing.widget.MegaMekButton.processMouseEvent(MegaMekButton.java:246)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    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:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    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:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
    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)

I have not been able to reproduce this running a game from MegaMek itself, only when running a game started from MekHQ.

I am including logs, customs, several brokenk save files, and a MekHQ save file with a scenrio ready to play that will reproduce this issue.

This is probably related to #6091 but that issue has less detail.

Steps to Reproduce

  1. Load included cpnx in mekhq
  2. Briefing tab, select pending scenario, start game
  3. Play Megamek, observe exceptions in log
  4. Attempt to load one of the saved games.

Operating System *

Linux

Java Version *

17.0.12

MegaMek Suite Version *

Free Text (type manually)

Custom MegaMek Version

v0.50.01-SNAPSHOT 2024-10-21

Attach Files

megamek.MegaMek.initializeLogging(MegaMek.java:146) - Starting MegaMek v0.50.1-SNAPSHOT Build Date: 2024-10-22T03:24:07.974368271 Today: 2024-10-21 Origin Project: MekHQ Java Vendor: Eclipse Adoptium Java Version: 17.0.12 Platform: Linux 6.11.3-200.fsync.fc40.x86_64 (amd64) System Locale: en_US Total memory available to MegaMek: 8 GB MM Code Revision: 630bba8695c2b1004e65501fe900f4e1b8c9e973 MML Code Revision: 384380362038ce744734c3a05836fd5d511d1df0 MHQ Code Revision: 035ff6c725a948b98d811bdaac45d7375ea67074

0.50.01-2024-10-21 Megamek Exception Spam.zip

Final Checklist

IllianiCBT commented 3 hours ago

This is going to be beyond my ability to resolve, as I suspect something has changed in mm to cause this.