From 1ca9e378cbd52c921ec6047df490ce1821f5d845 Mon Sep 17 00:00:00 2001 From: Octav Sandulescu Date: Thu, 22 Jun 2017 11:51:58 +0000 Subject: [PATCH] Work around 0.15.22 bug with disappearing GUIs As per the comment in the source, if a mod creates a GUI element whose name is both: - longer than 4 characters, and - less than 4 characters longer than the mod name, the element would be considered to belong to a mod that isn't present and get removed. We fixed this earlier in its guise as #71, which is how the bug appears in single-player, but in multiplayer the removal runs only client-side on joining, causing an instant desync for the joining player. My workaround is to rename the root element to evogui_root and hope (suspect, believe) that the remaining GUI elements all have longer names or won't cause instant breakage (so far, this seems to be holding). On the other hand, updating just EvoGUI while still on Factorio 0.15.22 needs to be a two-step process: save the game once, *then* reload it (start server, stop server, start server), as otherwise the client will cause the same desync again. It's possible just waiting until the first server autosave may also fix it, but it's quicker this way. Closes #74. --- VERSION | 2 +- evoGUI.lua | 34 +++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index 16680e7..bdca12e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.204 +0.4.205 diff --git a/evoGUI.lua b/evoGUI.lua index 5a9f656..c4dde8d 100644 --- a/evoGUI.lua +++ b/evoGUI.lua @@ -20,12 +20,32 @@ function evogui.mod_init() end end + +local function mod_update_0_4_205() + -- 0.4.204 to 0.4.205: Factorio 0.15.22 introduced a bug wherein a + -- GUI element with more than 4 characters in its name, which was + -- shorter than the_mod_name + 4 characters, would get deleted on + -- load. At this time, the EvoGUI root element switched from + -- gui.top.evoGUI to gui.top.evogui_root. + -- + -- We need to clean up the leftovers for people updating EvoGUI + -- from any other version of Factorio now. + for _, player in pairs(game.players) do + if player.gui.top.evoGUI then + player.gui.top.evoGUI.destroy() + end + end +end + + function evogui.mod_update(data) if data.mod_changes then if data.mod_changes["{{MOD_NAME}}"] then -- TODO: If a more major migration ever needs doing, do that here. -- Otherwise, just falling back to mod_init should work fine. evogui.mod_init() + + mod_update_0_4_205() end evogui.validate_sensors(data.mod_changes) @@ -72,7 +92,7 @@ function evogui.hide_sensor(sensor) for _, player in pairs(game.players) do local player_settings = global.evogui[player.name] - local sensor_flow = player.gui.top.evoGUI.sensor_flow + local sensor_flow = player.gui.top.evogui_root.sensor_flow evogui.update_av(player, sensor_flow.always_visible) end end @@ -96,11 +116,11 @@ function evogui.update_gui(event) if not player_settings then evogui.new_player({player_index = player_index}) player_settings = global.evogui[player.name] - elseif not player.gui.top.evoGUI then + elseif not player.gui.top.evogui_root then evogui.create_sensor_display(player) end - local sensor_flow = player.gui.top.evoGUI.sensor_flow + local sensor_flow = player.gui.top.evogui_root.sensor_flow evogui.update_av(player, sensor_flow.always_visible) if player_settings.popup_open then evogui.update_ip(player, sensor_flow.in_popup) @@ -171,16 +191,16 @@ end function evogui.create_sensor_display(player) - local root = player.gui.top.evoGUI + local root = player.gui.top.evogui_root local destroyed = false if root then - player.gui.top.evoGUI.destroy() + player.gui.top.evogui_root.destroy() destroyed = true end if not root or destroyed then local root = player.gui.top.add{type="frame", - name="evoGUI", + name="evogui_root", direction="horizontal", style="outer_frame_style"} @@ -249,7 +269,7 @@ function evogui.evoGUI_toggle_popup(event) local player = game.players[event.player_index] local player_settings = global.evogui[player.name] - local root = player.gui.top.evoGUI + local root = player.gui.top.evogui_root if player_settings.popup_open then -- close it