Bumber Posted September 2 Report Share Posted September 2 (edited) I tried giving myself a generic tree cutting "fruittree-cutting", which crashed the game. Now the game crashes whenever I join my world. I tried doing a sqlite3 recovery, but that doesn't fix the issue. Is there any way to get the block out of my inventory without loading the game? Or perhaps make the block not trigger a crash (e.g., JSON patching to fall back on an existing type?) System.ArgumentNullException: Value cannot be null. (Parameter 'key') at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at Vintagestory.GameContent.BlockFruitTreeBranch.OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ItemRenderInfo& renderinfo) in VSSurvivalMod\Systems\FruitTree\BlockFruitTreeBranch.cs:line 140 at Vintagestory.Client.NoObf.InventoryItemRenderer.GetItemStackRenderInfo(ClientMain game, ItemSlot inSlot, EnumItemRenderTarget target, Single dt) in VintagestoryLib\Client\Render\InventoryItemRenderer.cs:line 395 at Vintagestory.Client.NoObf.InventoryItemRenderer.RenderItemstackToGui(ItemSlot inSlot, Double posX, Double posY, Double posZ, Single size, Int32 color, Single dt, Boolean shading, Boolean origRotate, Boolean showStackSize) in VintagestoryLib\Client\Render\InventoryItemRenderer.cs:line 197 at Vintagestory.Client.NoObf.RenderAPIGame.RenderItemstackToGui(ItemSlot inSlot, Double posX, Double posY, Double posZ, Single size, Int32 color, Single dt, Boolean shading, Boolean rotate, Boolean showStackSize) in VintagestoryLib\Client\API\RenderAPIGame.cs:line 280 at Vintagestory.API.Client.GuiElementItemSlotGridBase.RenderInteractiveElements(Single deltaTime) in VintagestoryApi\Client\UI\Elements\Impl\Interactive\Inventory\GuiElementItemSlotGridBase.cs:line 479 at Vintagestory.API.Client.GuiComposer.Render(Single deltaTime) in VintagestoryApi\Client\UI\GuiComposer.cs:line 695 at Vintagestory.API.Client.GuiDialog.OnRenderGUI(Single deltaTime) in VintagestoryApi\Client\UI\Dialog\GuiDialog.cs:line 375 at Vintagestory.API.Client.HudElement.OnRenderGUI(Single deltaTime) in VintagestoryApi\Client\UI\HudElement.cs:line 30 at Vintagestory.Client.NoObf.HudHotbar.OnRenderGUI(Single deltaTime) in VintagestoryLib\Client\Systems\Gui\Huds\HudHotbar.cs:line 571 at Vintagestory.Client.NoObf.GuiManager.OnRenderFrameGUI(Single deltaTime) in VintagestoryLib\Client\Systems\Gui\GuiManager.cs:line 301 at Vintagestory.API.Client.DummyRenderer.OnRenderFrame(Single deltaTime, EnumRenderStage stage) in VintagestoryApi\Client\API\IClientEventAPI.cs:line 82 at Vintagestory.Client.NoObf.ClientEventManager.TriggerRenderStage(EnumRenderStage stage, Single dt) in VintagestoryLib\Client\Util\ClientEventManager.cs:line 191 at Vintagestory.Client.NoObf.ClientMain.TriggerRenderStage(EnumRenderStage stage, Single dt) in VintagestoryLib\Client\ClientMain.cs:line 787 at Vintagestory.Client.NoObf.ClientMain.RenderToDefaultFramebuffer(Single dt) in VintagestoryLib\Client\ClientMain.cs:line 965 at Vintagestory.Client.GuiScreenRunningGame.RenderToDefaultFramebuffer(Single dt) in VintagestoryLib\Client\MainMenu\Screens\GuiScreenRunningGame.cs:line 241 at Vintagestory.Client.ScreenManager.Render(Single dt) in VintagestoryLib\Client\ScreenManager.cs:line 668 at Vintagestory.Client.ScreenManager.OnNewFrame(Single dt) in VintagestoryLib\Client\ScreenManager.cs:line 643 at Vintagestory.Client.NoObf.ClientPlatformWindows.window_RenderFrame(FrameEventArgs e) in VintagestoryLib\Client\ClientPlatform\GameWindow.cs:line 76 at OpenTK.Windowing.Desktop.GameWindow.Run() at Vintagestory.Client.ClientProgram.Start(ClientProgramArgs args, String[] rawArgs) in VintagestoryLib\Client\ClientProgram.cs:line 312 at Vintagestory.Client.ClientProgram.<>c__DisplayClass9_0.<.ctor>b__1() in VintagestoryLib\Client\ClientProgram.cs:line 129 at Vintagestory.ClientNative.CrashReporter.Start(ThreadStart start) in VintagestoryLib\Client\ClientPlatform\ClientNative\CrashReporter.cs:line 93 Edited September 2 by Bumber Link to comment Share on other sites More sharing options...
Solution Bumber Posted September 3 Author Solution Report Share Posted September 3 Figured out a solution. The gist of it was to use sqlite3 to select the "data" column from "playerdata" and output that to a file I could open in a hex editor. There was some data that included slashes ('/') followed by the word "hotbar", which I guessed was info about where to find the player's hotbar data in the save. I opened the save file in a large hex editor and did a search for the data with slashes, which gave only 1 result. The hotbar data was a number 0-9 followed by some bytes until the next number. Empty slots aren't listed. I identified the slot with the bad item as the one right before the first empty slot (i.e., where a number is skipped.) I copied the previous slot's bytes over the one with the bad item. (I didn't delete the slot data in case doing so would have messed up other data.) The save loaded successfully and I had two hotbar slots containing an identical stack of 2 firewood, confirming that the bad item had been overwritten by it. Hopefully this can be of use to someone else. Link to comment Share on other sites More sharing options...
Recommended Posts