From bc6c2998b44d49d94bfba5a4bbeb850f5c9a932f Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 9 Feb 2011 17:14:25 +0000
Subject: [PATCH] Automated error reporting within the game (module
 independant)

git-svn-id: http://svn.net-core.org/repos/t-engine4@2692 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/Game.lua          |  7 +++
 game/engines/default/engine/PlayerProfile.lua |  9 +++
 game/modules/tome/class/Game.lua              |  5 +-
 .../tome/data/general/npcs/cold-drake.lua     |  2 +-
 premake4.lua                                  |  2 +-
 src/core_lua.c                                | 21 +++++++
 src/main.c                                    | 60 ++++++++++++++++++-
 src/main.h                                    | 12 ++++
 8 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/game/engines/default/engine/Game.lua b/game/engines/default/engine/Game.lua
index 5727318cb1..6c9f4aca61 100644
--- a/game/engines/default/engine/Game.lua
+++ b/game/engines/default/engine/Game.lua
@@ -20,6 +20,7 @@
 require "engine.class"
 require "engine.Mouse"
 require "engine.DebugConsole"
+require "engine.dialogs.ShowErrorStack"
 
 --- Represent a game
 -- A module should subclass it and initialize anything it needs to play inside
@@ -162,6 +163,12 @@ end
 
 --- This is the "main game loop", do something here
 function _M:tick()
+	-- Check out any possible errors
+	local errs = core.game.checkError()
+	if errs then
+		self:registerDialog(engine.dialogs.ShowErrorStack.new(errs))
+	end
+
 	local stop = {}
 	local id, co = next(self.__coroutines)
 	while id do
diff --git a/game/engines/default/engine/PlayerProfile.lua b/game/engines/default/engine/PlayerProfile.lua
index 7108dc858e..153f3563f1 100644
--- a/game/engines/default/engine/PlayerProfile.lua
+++ b/game/engines/default/engine/PlayerProfile.lua
@@ -237,6 +237,15 @@ function _M:getNews()
 	return self:rpc{action="GetNews", async=true}
 end
 
+function _M:sendError(what, err)
+	print("[ONLINE PROFILE] sending error")
+	local popup = Dialog:simplePopup("Sending...", "Sending the error report. Thank you.", nil, true)
+	popup.__showup = nil
+	core.display.forceRedraw()
+	self:rpc{action="SendError", login=self.login, what=what, err=err, module=game.__mod_info.short_name, version=game.__mod_info.version_name}
+	game:unregisterDialog(popup)
+end
+
 function _M:tryAuth()
 	print("[ONLINE PROFILE] auth")
 	local data = self:rpc{action="TryAuth", login=self.login, pass=self.pass}
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 72a31ec399..786024fc8b 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -828,8 +828,9 @@ function _M:setupCommands()
 		end end,
 		[{"_g","ctrl"}] = function() if config.settings.cheat then
 --			self.nicer_tiles:postProcessLevelTiles(self.level)
-			local m = game.zone:makeEntityByName(game.level, "actor", "NPC_COLD_DRAKE")
-			game.zone:addEntity(game.level, m, "actor", game.player.x + 1, game.player.y + 1)
+--			local m = game.zone:makeEntityByName(game.level, "actor", "NPC_COLD_DRAKE")
+--			game.zone:addEntity(game.level, m, "actor", game.player.x + 1, game.player.y + 1)
+			error("plop")
 		end end,
 	}
 
diff --git a/game/modules/tome/data/general/npcs/cold-drake.lua b/game/modules/tome/data/general/npcs/cold-drake.lua
index 40d6a6bbff..8db7f92b18 100644
--- a/game/modules/tome/data/general/npcs/cold-drake.lua
+++ b/game/modules/tome/data/general/npcs/cold-drake.lua
@@ -83,7 +83,7 @@ newEntity{ base = "BASE_NPC_COLD_DRAKE", define_as = "NPC_COLD_DRAKE",
 	},
 
 	resolvers.talents{
---		[Talents.T_SUMMON]=1,
+		[Talents.T_SUMMON]=1,
 		[Talents.T_ICE_CLAW]=2,
 		[Talents.T_ICE_BREATH]=3,
 	},
diff --git a/premake4.lua b/premake4.lua
index 6e27489766..c8f7759886 100644
--- a/premake4.lua
+++ b/premake4.lua
@@ -114,7 +114,7 @@ configuration "windows"
 	defines { [[TENGINE_HOME_PATH='"T-Engine"']], 'SELFEXE_WINDOWS' }
 
 configuration "linux"
-	links { "SDL", "SDL_ttf", "SDL_image", "SDL_mixer", "GL", "GLU", "m", "pthread" }
+	links { "SDL", "SDL_ttf", "SDL_image", "SDL_mixer", "GL", "GLU", "m", "pthread", "python2.6" }
 	defines { [[TENGINE_HOME_PATH='".t-engine"']], 'SELFEXE_LINUX' }
 
 configuration {"linux", "Debug"}
diff --git a/src/core_lua.c b/src/core_lua.c
index be482d0a41..a6e2cbc9dd 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -191,6 +191,26 @@ static int lua_sleep(lua_State *L)
 	SDL_Delay(ms);
 	return 0;
 }
+
+static int lua_check_error(lua_State *L)
+{
+	if (!last_lua_error_head) return 0;
+
+	int n = 1;
+	lua_newtable(L);
+	lua_err_type *cur = last_lua_error_head;
+	while (cur)
+	{
+		if (cur->err_msg) lua_pushfstring(L, "Lua Error: %s", cur->err_msg);
+		else lua_pushfstring(L, "  At %s:%d %s", cur->file, cur->line, cur->func);
+		lua_rawseti(L, -2, n++);
+		cur = cur->next;
+	}
+
+	del_lua_error();
+	return 1;
+}
+
 static const struct luaL_reg gamelib[] =
 {
 	{"reboot", lua_reboot_lua},
@@ -200,6 +220,7 @@ static const struct luaL_reg gamelib[] =
 	{"sleep", lua_sleep},
 	{"setRealtime", lua_set_realtime},
 	{"setFPS", lua_set_fps},
+	{"checkError", lua_check_error},
 	{NULL, NULL},
 };
 
diff --git a/src/main.c b/src/main.c
index 889d3fc7a9..fbe8e4a364 100644
--- a/src/main.c
+++ b/src/main.c
@@ -72,15 +72,71 @@ extern bool shaders_active;
 bool fbo_active;
 bool multitexture_active;
 
+/* Error handling */
+lua_err_type *last_lua_error_head = NULL, *last_lua_error_tail = NULL;
+
+void del_lua_error()
+{
+	lua_err_type *cur = last_lua_error_head;
+	while (cur)
+	{
+		if (cur->err_msg) free(cur->err_msg);
+		if (cur->file) free(cur->file);
+		if (cur->func) free(cur->func);
+
+		lua_err_type *ocur = cur;
+		cur = cur->next;
+		free(ocur);
+	}
+
+	last_lua_error_head = NULL;
+	last_lua_error_tail = NULL;
+}
+
+static void new_lua_error(const char *err)
+{
+	del_lua_error();
+
+	lua_err_type *cur = calloc(1, sizeof(lua_err_type));
+	cur->err_msg = strdup(err);
+	cur->next = NULL;
+
+	last_lua_error_head = cur;
+	last_lua_error_tail = cur;
+}
+
+static void add_lua_error(const char *file, int line, const char *func)
+{
+	lua_err_type *cur = calloc(1, sizeof(lua_err_type));
+	cur->err_msg = NULL;
+	cur->file = strdup(file);
+	cur->line = line;
+	cur->func = strdup(func);
+	cur->next = NULL;
+
+	last_lua_error_tail->next = cur;
+	last_lua_error_tail = cur;
+}
+
 static int traceback (lua_State *L) {
 	lua_Debug ar;
-	int n;
-	n = 0;
+	int n = 0;
 	printf("Lua Error: %s\n", lua_tostring(L, 1));
 	while(lua_getstack(L, n++, &ar)) {
 		lua_getinfo(L, "nSl", &ar);
 		printf("\tAt %s:%d %s\n", ar.short_src, ar.currentline, ar.name?ar.name:"");
 	}
+
+	// Do it again for the lua error popup, if needed
+	if (1)
+	{
+		n = 0;
+		new_lua_error(lua_tostring(L, 1));
+		while(lua_getstack(L, n++, &ar)) {
+			lua_getinfo(L, "nSl", &ar);
+			add_lua_error(ar.short_src, ar.currentline, ar.name?ar.name:"");
+		}
+	}
 	return 1;
 }
 
diff --git a/src/main.h b/src/main.h
index eb59b2ada2..b6f6523eff 100644
--- a/src/main.h
+++ b/src/main.h
@@ -29,5 +29,17 @@ extern bool fbo_active;
 extern bool multitexture_active;
 extern long total_keyframes;
 
+/* Error handling */
+struct lua_err_type_s {
+	char *err_msg;
+	char *file;
+	int line;
+	char *func;
+	struct lua_err_type_s *next;
+};
+typedef struct lua_err_type_s lua_err_type;
+extern lua_err_type *last_lua_error_head, *last_lua_error_tail;
+extern void del_lua_error();
+
 #endif
 
-- 
GitLab