From 7556cf933fd661f986e912e5f3a7d2ef7a776402 Mon Sep 17 00:00:00 2001
From: DarkGod <darkgod@net-core.org>
Date: Sun, 28 Dec 2014 18:41:25 +0100
Subject: [PATCH] Trying to load an old savefile from 1.2.5 will ask if you
 want to download the 1.2.5 data to play with

---
 game/engines/default/engine/Module.lua        |  6 +-
 .../default/engine/dialogs/Downloader.lua     |  2 +
 .../default/modules/boot/dialogs/LoadGame.lua | 70 +++++++++++++++++--
 3 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/game/engines/default/engine/Module.lua b/game/engines/default/engine/Module.lua
index 543924729d..cce57449ed 100644
--- a/game/engines/default/engine/Module.lua
+++ b/game/engines/default/engine/Module.lua
@@ -170,7 +170,7 @@ end
 
 --- List all available savefiles
 -- Static
-function _M:listSavefiles(moddir_filter)
+function _M:listSavefiles(incompatible_module, moddir_filter)
 	local allmounts = fs.getSearchPath(true)
 	fs.mount(engine.homepath..fs.getPathSeparator(), "/tmp/listsaves")
 
@@ -186,7 +186,7 @@ function _M:listSavefiles(moddir_filter)
 		end
 	end
 
-	local mods = self:listModules(nil, moddir_filter)
+	local mods = self:listModules(incompatible_module, moddir_filter)
 	for _, mod in ipairs(mods) do
 		local lss = {}
 		print("Listing saves for module", mod.short_name)
@@ -817,6 +817,8 @@ function _M:instanciate(mod, name, new_game, no_reboot, extra_module_info)
 
 	mod.version_name = ("%s-%d.%d.%d"):format(mod.short_name, mod.version[1], mod.version[2], mod.version[3])
 
+	print("[MODULE] booting module version", mod.version_name)
+
 	-- Make sure locale is correct
 	core.game.resetLocale()
 
diff --git a/game/engines/default/engine/dialogs/Downloader.lua b/game/engines/default/engine/dialogs/Downloader.lua
index 3ae6fd9549..b433b559ca 100644
--- a/game/engines/default/engine/dialogs/Downloader.lua
+++ b/game/engines/default/engine/dialogs/Downloader.lua
@@ -41,6 +41,8 @@ function _M:init(t)
 		end
 	end
 
+	print("[DOWNLOADER] downloading", self.url, "to", self.dest)
+
 	self.allow_downloads = t.allow_downloads or {}
 	self.allow_login = t.allow_login
 	self.custom_calls = t.custom_calls or {}
diff --git a/game/engines/default/modules/boot/dialogs/LoadGame.lua b/game/engines/default/modules/boot/dialogs/LoadGame.lua
index 3f20c2d1be..72badcc111 100644
--- a/game/engines/default/modules/boot/dialogs/LoadGame.lua
+++ b/game/engines/default/modules/boot/dialogs/LoadGame.lua
@@ -26,13 +26,14 @@ local Textzone = require "engine.ui.Textzone"
 local Separator = require "engine.ui.Separator"
 local Checkbox = require "engine.ui.Checkbox"
 local Savefile = require "engine.Savefile"
+local Downloader = require "engine.dialogs.Downloader"
 
 module(..., package.seeall, class.inherit(Dialog))
 
-function _M:init()
+function _M:init(force_compat)
 	Dialog.init(self, "Load Game", game.w * 0.8, game.h * 0.8)
 
-	self.c_compat = Checkbox.new{default=false, width=math.floor(self.iw / 3 - 40), title="Show older versions", on_change=function() self:switch() end}
+	self.c_compat = Checkbox.new{default=force_compat, width=math.floor(self.iw / 3 - 40), title="Show older versions", on_change=function() self:switch() end}
 	self.c_force_addons = Checkbox.new{default=false, width=math.floor(self.iw / 3 - 40), title="Ignore unloadable addons"}
 	self.c_play = Button.new{text="  Play!  ", fct=function(text) self:playSave() end}
 	self.c_delete = Button.new{text="Delete", fct=function(text) self:deleteSave() end}
@@ -80,7 +81,7 @@ function _M:init()
 end
 
 function _M:generateList()
-	local list = Module:listSavefiles()
+	local list = Module:listSavefiles(self.c_compat.checked)
 	self.tree = {}
 	local found = false
 	for i = #list, 1, -1 do
@@ -92,6 +93,7 @@ function _M:generateList()
 
 		for j, save in ipairs(m.savefiles) do
 			local mod_string = ("%s-%d.%d.%d"):format(m.short_name, save.module_version and save.module_version[1] or -1, save.module_version and save.module_version[2] or -1, save.module_version and save.module_version[3] or -1)
+			save.module_string = mod_string
 			local mod = list[mod_string]
 			if not mod and self.c_compat.checked and m.versions and m.versions[1] then mod = m.versions[1] end
 			if mod and save.loadable then
@@ -172,7 +174,7 @@ function _M:innerDisplay(x, y, nb_keyframes)
 	s[1]:toScreenFull(x + self.ix + self.iw - self.c_desc.w + 10, y + self.ih - h - 20, w, h, s[2] * w / s.w, s[3] * h / s.h)
 end
 
-function _M:playSave()
+function _M:playSave(ignore_mod_compat)
 	if not self.save_sel then return end
 
 	if self.save_sel.module == "tome" and engine.version_compare(self.save_sel.module_version, {1, 2, 0}) == "lower" then
@@ -189,6 +191,18 @@ We apologize for the annoyance, most of the time we try to keep compatibility bu
 		return
 	end
 
+	if not ignore_mod_compat and self.save_sel.module_string ~= self.save_sel.mod.version_string then
+		Dialog:yesnocancelLongPopup("Original game version not found", "This savefile was created with game version %s. You can try loading it with the current version if you wish or download the data files of the old version to ensure compatibility (this is a big download but only required once).", 500, function(ret, cancel)
+			if cancel then return end
+			if ret then
+				self:installOldGame(self.save_sel.module_string)
+			else
+				self:playSave(true)
+			end
+		end, "Install old data", "Run with newer version", "Cancel", true)
+		return
+	end
+
 	if config.settings.cheat and not self.save_sel.cheat then
 		Dialog:yesnoPopup("Developer Mode", "#LIGHT_RED#WARNING: #LAST#Loading a savefile while in developer mode will permanently invalidate it. Proceed?", function(ret) if not ret then
 			Module:instanciate(self.save_sel.mod, self.save_sel.base_name, false)
@@ -219,3 +233,51 @@ function _M:deleteSave()
 		end
 	end, "Delete", "Cancel")
 end
+
+function _M:installOldGame(version_string)
+	if not core.webview then return end
+	print("[OLD MODULE] checking for install", version_string)
+
+	local dls = {}
+	if version_string == "tome-1.2.5" then
+		dls[#dls+1] = {url="http://te4.org/dl/modules/tome/tome-1.2.5-gfx.team", name="tome-1.2.5-gfx.team"}
+		dls[#dls+1] = {url="http://te4.org/dl/modules/tome/tome-1.2.5-music.team", name="tome-1.2.5-music.team"}
+		dls[#dls+1] = {url="http://te4.org/dl/modules/tome/tome-1.2.5.team", name="tome-1.2.5.team"}
+	end
+
+	if #dls == 0 then
+		Dialog:simplePopup("Old game data", "No data available for this game version.")
+		return
+	end
+
+	local co co = coroutine.create(function()
+	local all_ok = true
+	for i, dl in ipairs(dls) do
+		local modfile = "/modules/"..dl.name
+		print("[OLD MODULE] download file from", dl.url, "to", modfile)
+		local d = Downloader.new{title="Downloading old game data: #LIGHT_GREEN#"..dl.name, co=co, dest=modfile..".tmp", url=dl.url, allow_downloads={modules=true}}
+		local ok = d:start()
+		if ok then
+			local wdir = fs.getWritePath()
+			local _, _, dir, name = modfile:find("(.+)/([^/]+)$")
+			if dir then
+				fs.setWritePath(fs.getRealPath(dir))
+				fs.delete(name)
+				fs.rename(name..".tmp", name)
+				fs.setWritePath(wdir)
+			end
+		else all_ok = false
+		end
+	end
+	if all_ok then Dialog:simplePopup("Old game data", "Old game data for "..version_string.." correctly installed. You can now play.") self:regen()
+	else Dialog:simplePopup("Old game data", "Failed to install.") end
+	end)
+	print(coroutine.resume(co))
+end
+
+function _M:regen()
+	local d = new(self.c_compat.checked)
+	d.__showup = false
+	game:replaceDialog(self, d)
+	self.next_dialog = d
+end
-- 
GitLab