From 5a9d4f89c2212c83f05f910b6f2a176f21048ba6 Mon Sep 17 00:00:00 2001 From: FakeTruth Date: Mon, 29 Jul 2013 02:37:59 +0200 Subject: [PATCH] WebAdmin templates can use Lua New WebAdmin templates can use Lua to completely compose the pages themselves. This should allow infinite WebAdmin design possibilities. --- MCServer/webadmin/template.lua | 453 +++++++++++++++++++++++++++++++++ VC2008/MCServer.vcproj | 8 + source/Bindings.cpp | 427 +++++++++++++++++++++++++++++-- source/Bindings.h | 2 +- source/LuaScript.cpp | 262 +++++++++++++++++++ source/LuaScript.h | 42 +++ source/ManualBindings.cpp | 61 +++++ source/Plugin_NewLua.cpp | 4 +- source/Plugin_NewLua.h | 4 +- source/Server.h | 2 +- source/WebAdmin.cpp | 302 ++++++++++++++-------- source/WebAdmin.h | 91 ++++--- source/WebPlugin.cpp | 2 +- source/WebPlugin.h | 9 +- 14 files changed, 1493 insertions(+), 176 deletions(-) create mode 100644 MCServer/webadmin/template.lua create mode 100644 source/LuaScript.cpp create mode 100644 source/LuaScript.h diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua new file mode 100644 index 000000000..f508ad5aa --- /dev/null +++ b/MCServer/webadmin/template.lua @@ -0,0 +1,453 @@ +-- Use a table for fast concatenation of strings +local SiteContent = {} +function Output(String) + table.insert(SiteContent, String) +end + +function GetTableSize(Table) + local Size = 0 + for key,value in pairs(Table) do + Size = Size + 1 + end + return Size +end + +function GetDefaultPage() + local PM = cRoot:Get():GetPluginManager() + + local SubTitle = "Current Game" + local Content = "" + + Content = Content .. "

Server Name:

" + Content = Content .. "

" .. cRoot:Get():GetServer():GetServerID() .. "

" + + Content = Content .. "

Plugins:

" + Content = Content .. "

Players:


"; + + return Content, SubTitle +end + +function ShowPage(WebAdmin, TemplateRequest) + SiteContent = {} + local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path) + local Title = "MCServer" + local MemoryUsage = WebAdmin:GetMemoryUsage() + local NumChunks = cRoot:Get():GetTotalChunkCount() + local PluginPage = WebAdmin:GetPage(TemplateRequest.Request) + local PageContent = PluginPage.Content + local SubTitle = PluginPage.PluginName + if (PluginPage.TabName ~= "") then + SubTitle = PluginPage.PluginName .. " - " .. PluginPage.TabName + end + if (PageContent == "") then + PageContent, SubTitle = GetDefaultPage() + end + + Output([[ + + + + +]] .. Title .. [[ + + + + + + +
+ +

+ MCServer +

+
+
+ + + +

Welcome ]] .. TemplateRequest.Request.Username .. [[

+
+

]] .. SubTitle .. [[

+ ]] .. PageContent .. [[ +
+ + +
+ +
+ +
+ + + +
+ + + + ]]) + + return table.concat(SiteContent) +end \ No newline at end of file diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 5d674ba43..c6876adbc 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1477,6 +1477,14 @@ RelativePath="..\source\LuaFunctions.h" > + + + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index fd85abba9..a81ec2b8c 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/26/13 21:48:46. +** Generated automatically by tolua++-1.0.92 on 07/29/13 02:06:10. */ #ifndef __cplusplus @@ -70,9 +70,9 @@ static int tolua_collect_cItem (lua_State* tolua_S) return 0; } -static int tolua_collect_Vector3f (lua_State* tolua_S) +static int tolua_collect_cFurnaceEntity (lua_State* tolua_S) { - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -140,9 +140,9 @@ static int tolua_collect_cPickup (lua_State* tolua_S) return 0; } -static int tolua_collect_cItems (lua_State* tolua_S) +static int tolua_collect_sWebAdminPage (lua_State* tolua_S) { - cItems* self = (cItems*) tolua_tousertype(tolua_S,1,0); + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -161,6 +161,13 @@ static int tolua_collect_cTracer (lua_State* tolua_S) return 0; } +static int tolua_collect_Vector3f (lua_State* tolua_S) +{ + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + static int tolua_collect_Vector3i (lua_State* tolua_S) { Vector3i* self = (Vector3i*) tolua_tousertype(tolua_S,1,0); @@ -168,16 +175,16 @@ static int tolua_collect_Vector3i (lua_State* tolua_S) return 0; } -static int tolua_collect_cFurnaceEntity (lua_State* tolua_S) +static int tolua_collect_cIniFile (lua_State* tolua_S) { - cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0); + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } -static int tolua_collect_cIniFile (lua_State* tolua_S) +static int tolua_collect_cItems (lua_State* tolua_S) { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + cItems* self = (cItems*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -205,32 +212,34 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); tolua_usertype(tolua_S,"cWindow"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cPickup"); tolua_usertype(tolua_S,"cItems"); - tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cChunkDesc"); tolua_usertype(tolua_S,"cFurnaceRecipe"); - tolua_usertype(tolua_S,"cGroup"); - tolua_usertype(tolua_S,"cChatColor"); - tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cCuboid"); - tolua_usertype(tolua_S,"Lua__cWebPlugin"); + tolua_usertype(tolua_S,"cChatColor"); tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"cEntity"); + tolua_usertype(tolua_S,"Lua__cWebPlugin"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cCraftingRecipes"); tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"Vector3f"); - tolua_usertype(tolua_S,"cWebAdmin"); + tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"cDropSpenserEntity"); tolua_usertype(tolua_S,"Lua__cPlayer"); - tolua_usertype(tolua_S,"cCraftingRecipes"); + tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"cChestEntity"); tolua_usertype(tolua_S,"cDispenserEntity"); - tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cWebAdmin"); tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cCriticalSection"); - tolua_usertype(tolua_S,"Lua__cPickup"); - tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"HTTPTemplateRequest"); + tolua_usertype(tolua_S,"sWebAdminPage"); tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"HTTPFormData"); tolua_usertype(tolua_S,"cFurnaceEntity"); @@ -11092,6 +11101,38 @@ static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetServerID of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetServerID00 +static int tolua_AllToLua_cServer_GetServerID00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cServer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cServer* self = (const cServer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetServerID'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetServerID(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetServerID'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetClassStatic of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetClassStatic00 static int tolua_AllToLua_cWorld_GetClassStatic00(lua_State* tolua_S) @@ -18410,7 +18451,7 @@ static int tolua_set_HTTPRequest_Method(lua_State* tolua_S) if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); #endif - self->Method = ((std::string) tolua_tocppstring(tolua_S,2,0)) + self->Method = ((AString) tolua_tocppstring(tolua_S,2,0)) ; return 0; } @@ -18440,7 +18481,7 @@ static int tolua_set_HTTPRequest_Path(lua_State* tolua_S) if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); #endif - self->Path = ((std::string) tolua_tocppstring(tolua_S,2,0)) + self->Path = ((AString) tolua_tocppstring(tolua_S,2,0)) ; return 0; } @@ -18470,12 +18511,307 @@ static int tolua_set_HTTPRequest_Username(lua_State* tolua_S) if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); #endif - self->Username = ((std::string) tolua_tocppstring(tolua_S,2,0)) + self->Username = ((AString) tolua_tocppstring(tolua_S,2,0)) ; return 0; } #endif //#ifndef TOLUA_DISABLE +/* get function: Request of class HTTPTemplateRequest */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPTemplateRequest_Request +static int tolua_get_HTTPTemplateRequest_Request(lua_State* tolua_S) +{ + HTTPTemplateRequest* self = (HTTPTemplateRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Request'",NULL); +#endif + tolua_pushusertype(tolua_S,(void*)&self->Request,"HTTPRequest"); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Request of class HTTPTemplateRequest */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPTemplateRequest_Request +static int tolua_set_HTTPTemplateRequest_Request(lua_State* tolua_S) +{ + HTTPTemplateRequest* self = (HTTPTemplateRequest*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Request'",NULL); + if ((tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err))) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Request = *((HTTPRequest*) tolua_tousertype(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Content of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_get_sWebAdminPage_Content +static int tolua_get_sWebAdminPage_Content(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Content'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Content); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Content of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_set_sWebAdminPage_Content +static int tolua_set_sWebAdminPage_Content(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Content'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Content = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: PluginName of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_get_sWebAdminPage_PluginName +static int tolua_get_sWebAdminPage_PluginName(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'PluginName'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->PluginName); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: PluginName of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_set_sWebAdminPage_PluginName +static int tolua_set_sWebAdminPage_PluginName(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'PluginName'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->PluginName = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: TabName of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_get_sWebAdminPage_TabName +static int tolua_get_sWebAdminPage_TabName(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'TabName'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->TabName); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: TabName of class sWebAdminPage */ +#ifndef TOLUA_DISABLE_tolua_set_sWebAdminPage_TabName +static int tolua_set_sWebAdminPage_TabName(lua_State* tolua_S) +{ + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'TabName'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->TabName = ((AString) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPort of class cWebAdmin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebAdmin_GetPort00 +static int tolua_AllToLua_cWebAdmin_GetPort00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebAdmin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPort'", NULL); +#endif + { + int tolua_ret = (int) self->GetPort(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPort'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetPage of class cWebAdmin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebAdmin_GetPage00 +static int tolua_AllToLua_cWebAdmin_GetPage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebAdmin",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const HTTPRequest",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S,1,0); + const HTTPRequest* a_Request = ((const HTTPRequest*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPage'", NULL); +#endif + { + sWebAdminPage tolua_ret = (sWebAdminPage) self->GetPage(*a_Request); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((sWebAdminPage)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"sWebAdminPage"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(sWebAdminPage)); + tolua_pushusertype(tolua_S,tolua_obj,"sWebAdminPage"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetPage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBaseURL of class cWebAdmin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebAdmin_GetBaseURL00 +static int tolua_AllToLua_cWebAdmin_GetBaseURL00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWebAdmin",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S,1,0); + const AString a_URL = ((const AString) tolua_tocppstring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBaseURL'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetBaseURL(a_URL); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + tolua_pushcppstring(tolua_S,(const char*)a_URL); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBaseURL'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMemoryUsage of class cWebAdmin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebAdmin_GetMemoryUsage00 +static int tolua_AllToLua_cWebAdmin_GetMemoryUsage00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWebAdmin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWebAdmin* self = (const cWebAdmin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMemoryUsage'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetMemoryUsage(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMemoryUsage'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetWebTitle of class cWebPlugin */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_GetWebTitle00 +static int tolua_AllToLua_cWebPlugin_GetWebTitle00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWebPlugin",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWebPlugin* self = (const cWebPlugin*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWebTitle'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetWebTitle(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWebTitle'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: HandleWebRequest of class cWebPlugin */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWebPlugin_HandleWebRequest00 static int tolua_AllToLua_cWebPlugin_HandleWebRequest00(lua_State* tolua_S) @@ -18484,7 +18820,7 @@ static int tolua_AllToLua_cWebPlugin_HandleWebRequest00(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cWebPlugin",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"HTTPRequest",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"const HTTPRequest",0,&tolua_err) || !tolua_isnoobj(tolua_S,3,&tolua_err) ) goto tolua_lerror; @@ -18492,7 +18828,7 @@ static int tolua_AllToLua_cWebPlugin_HandleWebRequest00(lua_State* tolua_S) #endif { cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); - HTTPRequest* a_Request = ((HTTPRequest*) tolua_tousertype(tolua_S,2,0)); + const HTTPRequest* a_Request = ((const HTTPRequest*) tolua_tousertype(tolua_S,2,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleWebRequest'", NULL); #endif @@ -18543,9 +18879,25 @@ static int tolua_AllToLua_cWebPlugin_SafeString00(lua_State* tolua_S) class Lua__cWebPlugin : public cWebPlugin, public ToluaBase { public: - AString HandleWebRequest( HTTPRequest* a_Request) { + const AString GetWebTitle( void )const { + if (push_method("GetWebTitle", tolua_AllToLua_cWebPlugin_GetWebTitle00)) { + ToluaBase::dbcall(lua_state, 1, 1); + const AString tolua_ret = ( const AString )tolua_tocppstring(lua_state, -1, 0); + lua_pop(lua_state, 1); + return tolua_ret; + } else { + if (lua_state) + LOG("pure-virtual method cWebPlugin::GetWebTitle not implemented."); + else { + LOG("pure-virtual method cWebPlugin::GetWebTitle called with no lua_state. Aborting"); + ::abort(); + }; + return ( const AString )0; + }; + }; + AString HandleWebRequest( const HTTPRequest* a_Request) { if (push_method("HandleWebRequest", tolua_AllToLua_cWebPlugin_HandleWebRequest00)) { - tolua_pushusertype(lua_state, (void*)a_Request, "HTTPRequest"); + tolua_pushusertype(lua_state, (void*)a_Request, "const HTTPRequest"); ToluaBase::dbcall(lua_state, 2, 1); AString tolua_ret = ( AString )tolua_tocppstring(lua_state, -1, 0); lua_pop(lua_state, 1); @@ -29025,6 +29377,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_beginmodule(tolua_S,"cServer"); tolua_function(tolua_S,"BroadcastChat",tolua_AllToLua_cServer_BroadcastChat00); tolua_function(tolua_S,"SendMessage",tolua_AllToLua_cServer_SendMessage00); + tolua_function(tolua_S,"GetServerID",tolua_AllToLua_cServer_GetServerID00); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cWorld","cWorld","",NULL); tolua_beginmodule(tolua_S,"cWorld"); @@ -29372,8 +29725,30 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username); tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPTemplateRequest","HTTPTemplateRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPTemplateRequest"); + tolua_variable(tolua_S,"Request",tolua_get_HTTPTemplateRequest_Request,tolua_set_HTTPTemplateRequest_Request); + tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"sWebAdminPage","sWebAdminPage","",tolua_collect_sWebAdminPage); + #else + tolua_cclass(tolua_S,"sWebAdminPage","sWebAdminPage","",NULL); + #endif + tolua_beginmodule(tolua_S,"sWebAdminPage"); + tolua_variable(tolua_S,"Content",tolua_get_sWebAdminPage_Content,tolua_set_sWebAdminPage_Content); + tolua_variable(tolua_S,"PluginName",tolua_get_sWebAdminPage_PluginName,tolua_set_sWebAdminPage_PluginName); + tolua_variable(tolua_S,"TabName",tolua_get_sWebAdminPage_TabName,tolua_set_sWebAdminPage_TabName); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cWebAdmin","cWebAdmin","",NULL); + tolua_beginmodule(tolua_S,"cWebAdmin"); + tolua_function(tolua_S,"GetPort",tolua_AllToLua_cWebAdmin_GetPort00); + tolua_function(tolua_S,"GetPage",tolua_AllToLua_cWebAdmin_GetPage00); + tolua_function(tolua_S,"GetBaseURL",tolua_AllToLua_cWebAdmin_GetBaseURL00); + tolua_function(tolua_S,"GetMemoryUsage",tolua_AllToLua_cWebAdmin_GetMemoryUsage00); + tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cWebPlugin","cWebPlugin","",NULL); tolua_beginmodule(tolua_S,"cWebPlugin"); + tolua_function(tolua_S,"GetWebTitle",tolua_AllToLua_cWebPlugin_GetWebTitle00); tolua_function(tolua_S,"HandleWebRequest",tolua_AllToLua_cWebPlugin_HandleWebRequest00); tolua_function(tolua_S,"SafeString",tolua_AllToLua_cWebPlugin_SafeString00); tolua_endmodule(tolua_S); diff --git a/source/Bindings.h b/source/Bindings.h index c21612525..a86df572c 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/26/13 21:48:46. +** Generated automatically by tolua++-1.0.92 on 07/29/13 02:06:11. */ /* Exported function */ diff --git a/source/LuaScript.cpp b/source/LuaScript.cpp new file mode 100644 index 000000000..b55ff3520 --- /dev/null +++ b/source/LuaScript.cpp @@ -0,0 +1,262 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "LuaScript.h" + +extern "C" +{ +#include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +// fwd: SQLite/lsqlite3.c +extern "C" +{ + LUALIB_API int luaopen_lsqlite3(lua_State * L); +} + +// fwd: LuaExpat/lxplib.c: +extern "C" +{ + int luaopen_lxp(lua_State * L); +} + + + + + +cLuaScript::cLuaScript() + : m_LuaState(NULL) +{ + +} + + + + + +cLuaScript::~cLuaScript() +{ + if( m_LuaState ) + { + lua_close( m_LuaState ); + m_LuaState = 0; + } +} + + + + + +void cLuaScript::Initialize() +{ + // Check to see if this script has not been initialized before + ASSERT(!m_LuaState); + + // Create a Lua state and bind all libraries to it + m_LuaState = lua_open(); + luaL_openlibs(m_LuaState); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind(m_LuaState); + luaopen_lsqlite3(m_LuaState); + luaopen_lxp(m_LuaState); +} + + + + + +bool cLuaScript::LoadFile( const char* a_FilePath ) +{ + // Make sure the plugin is initialized + ASSERT(m_LuaState); + + // Load the file into the Lua state + int s = luaL_loadfile(m_LuaState, a_FilePath ); + if (ReportErrors(s)) + { + return false; + } + return true; +} + + + + + +bool cLuaScript::Execute() +{ + // Make sure we got a Lua state + ASSERT(m_LuaState); + + // Execute the script as it is right now + int s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if( ReportErrors( s ) ) + { + return false; + } + return true; +} + + + + + +bool cLuaScript::ReportErrors( int a_Status ) +{ + if (a_Status == 0) + { + // No error to report + return false; + } + + // Status was set to error so get the error from the Lua state and log it + LOGERROR("LUA: %s", lua_tostring(m_LuaState, -1)); + lua_pop(m_LuaState, 1); + + // Return true to indicate that an error was returned + return true; +} + + + + + +bool cLuaScript::LuaPushFunction( const char * a_FunctionName, bool a_bLogError /*= true*/ ) +{ + ASSERT(m_LuaState); + + // Find and push the function on the Lua stack + lua_getglobal(m_LuaState, a_FunctionName); + + // Make sure we found a function + if (!lua_isfunction(m_LuaState, -1)) + { + if (a_bLogError) + { + LOGWARN("LUA: Could not find function %s()", a_FunctionName); + } + + // Pop the pushed 'object' back + lua_pop(m_LuaState, 1); + return false; + } + + // Successfully pushed a function to the Lua stack + return true; +} + + + + + +bool cLuaScript::LuaCallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName ) +{ + ASSERT(m_LuaState); + + // Make sure there's a lua function on the stack + ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + + // Call the desired function + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + + // Check for errors + if (ReportErrors(s)) + { + LOGWARN("LUA: Error calling function %s()", a_FunctionName); + return false; + } + + // Successfully executed function + return true; +} + + + + + +bool cLuaScript::CallFunction( const char* a_Function, AString& ReturnedString ) +{ + // Make sure we have the required things to call a function + ASSERT(m_LuaState); + ASSERT(a_Function); + + // Push the desired function on the stack + if (!LuaPushFunction(a_Function)) + return false; + + if (!LuaCallFunction(0, 1, a_Function)) + return false; + + if (lua_isstring(m_LuaState, -1)) + { + ReturnedString = tolua_tostring(m_LuaState, -1, ""); + } + lua_pop(m_LuaState, 1); + return true; +} + + + + + +bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType, AString& ReturnedString ) +{ + // Make sure we have the required things to call a function + ASSERT(m_LuaState); + ASSERT(a_Function); + + // Push the desired function on the stack + if (!LuaPushFunction(a_Function)) + return false; + + tolua_pushusertype(m_LuaState, a_UserType.Object, a_UserType.ClassName); + + if (!LuaCallFunction(1, 1, a_Function)) + return false; + + if (lua_isstring(m_LuaState, -1)) + { + ReturnedString = tolua_tostring(m_LuaState, -1, ""); + } + lua_pop(m_LuaState, 1); + return true; +} + + + + + +bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType1, const sLuaUsertype& a_UserType2, AString& ReturnedString ) +{ + // Make sure we have the required things to call a function + ASSERT(m_LuaState); + ASSERT(a_Function); + + // Push the desired function on the stack + if (!LuaPushFunction(a_Function)) + return false; + + tolua_pushusertype(m_LuaState, a_UserType1.Object, a_UserType1.ClassName); + tolua_pushusertype(m_LuaState, a_UserType2.Object, a_UserType2.ClassName); + + if (!LuaCallFunction(2, 1, a_Function)) + return false; + + if (lua_isstring(m_LuaState, -1)) + { + ReturnedString = tolua_tostring(m_LuaState, -1, ""); + } + lua_pop(m_LuaState, 1); + return true; +} + + + + + + + diff --git a/source/LuaScript.h b/source/LuaScript.h new file mode 100644 index 000000000..cf4806903 --- /dev/null +++ b/source/LuaScript.h @@ -0,0 +1,42 @@ +#pragma once + +struct lua_State; + +struct sLuaUsertype +{ + sLuaUsertype(void* a_pObject, const char* a_pClassName) : Object(a_pObject), ClassName(a_pClassName) {} + // + void* Object; + const char* ClassName; +}; + +class cLuaScript +{ +public: + cLuaScript(); + ~cLuaScript(); + + /// Prepares a Lua state + void Initialize(); + + /// Load a Lua script on the given path + bool LoadFile(const char* a_FilePath); + + /// Execute the loaded Lua script + bool Execute(); + + /// Call a function on the Lua script. Put all overloads here + bool CallFunction(const char* a_Function, AString& ReturnedString); + bool CallFunction(const char* a_Function, const sLuaUsertype& a_UserType, AString& ReturnedString); + bool CallFunction(const char* a_Function, const sLuaUsertype& a_UserType1, const sLuaUsertype& a_UserType2, AString& ReturnedString); + +protected: + /// Reports an error in the log if a_Status is flagged as an error. Returns true when a_Status is flagged as error, returns false when no error occured. + bool ReportErrors(int a_Status); + + /// Helper functions for calling functions in Lua + bool LuaPushFunction(const char * a_FunctionName, bool a_bLogError = true); + bool LuaCallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else +private: + lua_State* m_LuaState; +}; \ No newline at end of file diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 30648a8b7..7a13d94c0 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -1272,6 +1272,59 @@ static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) +static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) +{ + cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S,1,0); + + const cWebAdmin::PluginList & AllPlugins = self->GetPlugins(); + + lua_createtable(tolua_S, AllPlugins.size(), 0); + int newTable = lua_gettop(tolua_S); + int index = 1; + cWebAdmin::PluginList::const_iterator iter = AllPlugins.begin(); + while(iter != AllPlugins.end()) + { + const cWebPlugin* Plugin = *iter; + tolua_pushusertype( tolua_S, (void*)Plugin, "const cWebPlugin" ); + lua_rawseti(tolua_S, newTable, index); + ++iter; + ++index; + } + return 1; +} + + + + + +static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) +{ + cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S,1,0); + + const cWebPlugin::TabNameList & TabNames = self->GetTabNames(); + + lua_newtable(tolua_S); + int newTable = lua_gettop(tolua_S); + int index = 1; + cWebPlugin::TabNameList::const_iterator iter = TabNames.begin(); + while(iter != TabNames.end()) + { + const AString & FancyName = iter->first; + const AString & WebName = iter->second; + tolua_pushstring( tolua_S, WebName.c_str() ); // Because the WebName is supposed to be unique, use it as key + tolua_pushstring( tolua_S, FancyName.c_str() ); + // + lua_rawset(tolua_S, -3); + ++iter; + ++index; + } + return 1; +} + + + + + static int Lua_ItemGrid_GetSlotCoords(lua_State * L) { tolua_Error tolua_err; @@ -1377,6 +1430,14 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S, "cWebAdmin"); + tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); + tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S, "cWebPlugin"); + tolua_function(tolua_S, "GetTabNames", tolua_cWebPlugin_GetTabNames); + tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cClientHandle"); tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index c79106761..f4c05ab42 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -1565,7 +1565,7 @@ const char * cPlugin_NewLua::GetHookFnName(cPluginManager::PluginHook a_Hook) -AString cPlugin_NewLua::HandleWebRequest( HTTPRequest * a_Request ) +AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) { cCSLock Lock(m_CriticalSection); std::string RetVal = ""; @@ -1592,7 +1592,7 @@ AString cPlugin_NewLua::HandleWebRequest( HTTPRequest * a_Request ) //LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest - tolua_pushusertype( m_LuaState, a_Request, "HTTPRequest" ); + tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); //LOGINFO("Calling bound function! :D"); int s = lua_pcall( m_LuaState, 1, 1, 0); diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index 8d51c86f6..1ca208e9d 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -86,10 +86,10 @@ public: virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) override; // cWebPlugin override - virtual const AString & GetWebTitle(void) const {return GetName(); } + virtual const AString GetWebTitle(void) const {return GetName(); } // cWebPlugin and WebAdmin stuff - virtual AString HandleWebRequest( HTTPRequest * a_Request ) override; + virtual AString HandleWebRequest(const HTTPRequest * a_Request ) override; bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS << /// Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap. diff --git a/source/Server.h b/source/Server.h index 542673b49..dd7a08735 100644 --- a/source/Server.h +++ b/source/Server.h @@ -60,7 +60,7 @@ public: // tolua_export void KickUser(int a_ClientID, const AString & a_Reason); void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user - const AString & GetServerID(void) const; + const AString & GetServerID(void) const; // tolua_export void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client diff --git a/source/WebAdmin.cpp b/source/WebAdmin.cpp index dd1a695ee..11a5bd379 100644 --- a/source/WebAdmin.cpp +++ b/source/WebAdmin.cpp @@ -13,6 +13,7 @@ #include "Player.h" #include "Server.h" #include "Root.h" +#include "LuaScript.h" #include "../iniFile/iniFile.h" @@ -59,6 +60,7 @@ cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) { WebAdmin = this; m_Event = new cEvent(); + m_pTemplate = new cLuaScript(); Init( m_Port ); } @@ -68,10 +70,12 @@ cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) cWebAdmin::~cWebAdmin() { + WebAdmin = 0; m_WebServer->Stop(); delete m_WebServer; + delete m_pTemplate; delete m_IniFile; m_Event->Wait(); @@ -146,40 +150,17 @@ void cWebAdmin::Request_Handler(webserver::http_request* r) bDontShowTemplate = true; } - std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); + AString UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); if ((UserPassword != "") && (r->password_ == UserPassword)) { - std::string BaseURL = "./"; - if (Split.size() > 1) - { - for (unsigned int i = 0; i < Split.size(); i++) - { - BaseURL += "../"; - } - BaseURL += "webadmin/"; - } + AString Template; - std::string Menu; - std::string Content; - std::string Template = bDontShowTemplate ? "{CONTENT}" : WebAdmin->GetTemplate(); - std::string FoundPlugin; - - for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) - { - cWebPlugin* WebPlugin = *itr; - std::list< std::pair > NameList = WebPlugin->GetTabNames(); - for( std::list< std::pair >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names ) - { - Menu += "
  • " + (*Names).first + "
  • "; - } - } - - HTTPRequest Request; - Request.Username = r->username_; - Request.Method = r->method_; - Request.Params = r->params_; - Request.PostParams = r->params_post_; - Request.Path = r->path_.substr(1); + HTTPTemplateRequest TemplateRequest; + TemplateRequest.Request.Username = r->username_; + TemplateRequest.Request.Method = r->method_; + TemplateRequest.Request.Params = r->params_; + TemplateRequest.Request.PostParams = r->params_post_; + TemplateRequest.Request.Path = r->path_.substr(1); for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i ) { @@ -190,101 +171,113 @@ void cWebAdmin::Request_Handler(webserver::http_request* r) HTTPfd.Type = fd.content_type_; HTTPfd.Name = fd.name_; LOGINFO("Form data name: %s", fd.name_.c_str() ); - Request.FormData[ fd.name_ ] = HTTPfd; + TemplateRequest.Request.FormData[ fd.name_ ] = HTTPfd; } - if (Split.size() > 1) + bool bLuaTemplateSuccessful = false; + if (!bDontShowTemplate) { + // New Lua web template + bLuaTemplateSuccessful = WebAdmin->m_pTemplate->CallFunction("ShowPage", sLuaUsertype(WebAdmin, "cWebAdmin"), sLuaUsertype(&TemplateRequest, "HTTPTemplateRequest"), Template); + } + + if (!bLuaTemplateSuccessful) + { + AString BaseURL = WebAdmin->GetBaseURL(Split); + AString Menu; + Template = bDontShowTemplate ? "{CONTENT}" : WebAdmin->GetTemplate(); + AString FoundPlugin; + for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) { - if ((*itr)->GetWebTitle() == Split[1]) + cWebPlugin* WebPlugin = *itr; + std::list< std::pair > NameList = WebPlugin->GetTabNames(); + for( std::list< std::pair >::iterator Names = NameList.begin(); Names != NameList.end(); ++Names ) { - Content = (*itr)->HandleWebRequest(&Request); - cWebPlugin * WebPlugin = *itr; - FoundPlugin = WebPlugin->GetWebTitle(); - AString TabName = WebPlugin->GetTabNameForRequest(&Request).first; - if (!TabName.empty()) + Menu += "
  • " + (*Names).first + "
  • "; + } + } + + sWebAdminPage Page = WebAdmin->GetPage(TemplateRequest.Request); + AString Content = Page.Content; + FoundPlugin = Page.PluginName; + if (!Page.TabName.empty()) + FoundPlugin += " - " + Page.TabName; + + if( FoundPlugin.empty() ) // Default page + { + Content.clear(); + FoundPlugin = "Current Game"; + Content += "

    Server Name:

    "; + Content += "

    " + AString( cRoot::Get()->GetServer()->GetServerID() ) + "

    "; + + Content += "

    Plugins:

      "; + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + if( PM ) + { + const cPluginManager::PluginMap & List = PM->GetAllPlugins(); + for( cPluginManager::PluginMap::const_iterator itr = List.begin(); itr != List.end(); ++itr ) { - FoundPlugin += " - " + TabName; + if( itr->second == NULL ) continue; + AString VersionNum; + AppendPrintf(Content, "
    • %s V.%i
    • ", itr->second->GetName().c_str(), itr->second->GetVersion()); } - break; } - } - } + Content += "
    "; + Content += "

    Players:

      "; - if( FoundPlugin.empty() ) // Default page - { - Content.clear(); - FoundPlugin = "Current Game"; - Content += "

      Server Name:

      "; - Content += "

      " + std::string( cRoot::Get()->GetServer()->GetServerID() ) + "

      "; - - Content += "

      Plugins:

        "; - cPluginManager* PM = cRoot::Get()->GetPluginManager(); - if( PM ) - { - const cPluginManager::PluginMap & List = PM->GetAllPlugins(); - for( cPluginManager::PluginMap::const_iterator itr = List.begin(); itr != List.end(); ++itr ) + cPlayerAccum PlayerAccum; + cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players + if( World != NULL ) { - if( itr->second == NULL ) continue; - AString VersionNum; - AppendPrintf(Content, "
      • %s V.%i
      • ", itr->second->GetName().c_str(), itr->second->GetVersion()); + World->ForEachPlayer(PlayerAccum); + Content.append(PlayerAccum.m_Contents); } + Content += "

      "; } - Content += "
    "; - Content += "

    Players:

      "; - cPlayerAccum PlayerAccum; - cWorld * World = cRoot::Get()->GetDefaultWorld(); // TODO - Create a list of worlds and players - if( World != NULL ) + + + if (!bDontShowTemplate && (Split.size() > 1)) { - World->ForEachPlayer(PlayerAccum); - Content.append(PlayerAccum.m_Contents); + Content += "\n

      Go back

      "; } - Content += "

    "; - } - - - if (!bDontShowTemplate && (Split.size() > 1)) - { - Content += "\n

    Go back

    "; - } - - // mem usage + // mem usage #ifndef _WIN32 - rusage resource_usage; - if (getrusage(RUSAGE_SELF, &resource_usage) != 0) - { - ReplaceString( Template, std::string("{MEM}"), "Error :(" ); - } - else - { - AString MemUsage; - Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); - ReplaceString(Template, std::string("{MEM}"), MemUsage); - } + rusage resource_usage; + if (getrusage(RUSAGE_SELF, &resource_usage) != 0) + { + ReplaceString( Template, AString("{MEM}"), "Error :(" ); + } + else + { + AString MemUsage; + Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); + ReplaceString(Template, AString("{MEM}"), MemUsage); + } #else - HANDLE hProcess = GetCurrentProcess(); - PROCESS_MEMORY_COUNTERS pmc; - if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) - { - AString MemUsage; - Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); - ReplaceString( Template, "{MEM}", MemUsage ); - } + HANDLE hProcess = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS pmc; + if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) + { + AString MemUsage; + Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); + ReplaceString( Template, "{MEM}", MemUsage ); + } #endif - // end mem usage + // end mem usage - ReplaceString( Template, "{USERNAME}", r->username_ ); - ReplaceString( Template, "{MENU}", Menu ); - ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin ); - ReplaceString( Template, "{CONTENT}", Content ); - ReplaceString( Template, "{TITLE}", "MCServer" ); + ReplaceString( Template, "{USERNAME}", r->username_ ); + ReplaceString( Template, "{MENU}", Menu ); + ReplaceString( Template, "{PLUGIN_NAME}", FoundPlugin ); + ReplaceString( Template, "{CONTENT}", Content ); + ReplaceString( Template, "{TITLE}", "MCServer" ); - AString NumChunks; - Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); - ReplaceString(Template, "{NUMCHUNKS}", NumChunks); + AString NumChunks; + Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); + ReplaceString(Template, "{NUMCHUNKS}", NumChunks); + } r->answer_ = Template; } @@ -309,6 +302,14 @@ bool cWebAdmin::Init( int a_Port ) m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); } + // Initialize the WebAdmin template script and load the file + m_pTemplate->Initialize(); + if (!m_pTemplate->LoadFile( FILE_IO_PREFIX "webadmin/template.lua") || !m_pTemplate->Execute()) + { + LOGWARN("Could not load WebAdmin template."); + } + + LOG("Starting WebAdmin on port %i", m_Port); #ifdef _WIN32 @@ -354,9 +355,9 @@ void *cWebAdmin::ListenThread( void *lpParam ) -std::string cWebAdmin::GetTemplate() +AString cWebAdmin::GetTemplate() { - std::string retVal = ""; + AString retVal = ""; char SourceFile[] = "webadmin/template.html"; @@ -370,4 +371,91 @@ std::string cWebAdmin::GetTemplate() f.ReadRestOfFile(retVal); return retVal; -} \ No newline at end of file +} + + + + + +sWebAdminPage cWebAdmin::GetPage(const HTTPRequest& a_Request) +{ + sWebAdminPage Page; + AStringVector Split = StringSplit(a_Request.Path, "/"); + + // Find the plugin that corresponds to the requested path + AString FoundPlugin; + if (Split.size() > 1) + { + for (PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr) + { + if ((*itr)->GetWebTitle() == Split[1]) + { + Page.Content = (*itr)->HandleWebRequest(&a_Request); + cWebPlugin * WebPlugin = *itr; + FoundPlugin = WebPlugin->GetWebTitle(); + AString TabName = WebPlugin->GetTabNameForRequest(&a_Request).first; + Page.PluginName = FoundPlugin; + Page.TabName = TabName; + break; + } + } + } + + // Return the page contents + return Page; +} + + + + + +AString cWebAdmin::GetBaseURL( const AString& a_URL ) +{ + return GetBaseURL(StringSplit(a_URL, "/")); +} + + + + + +AString cWebAdmin::GetBaseURL( const AStringVector& a_URLSplit ) +{ + AString BaseURL = "./"; + if (a_URLSplit.size() > 1) + { + for (unsigned int i = 0; i < a_URLSplit.size(); i++) + { + BaseURL += "../"; + } + BaseURL += "webadmin/"; + } + return BaseURL; +} + + + + + +AString cWebAdmin::GetMemoryUsage() const +{ + AString MemUsage; +#ifndef _WIN32 + rusage resource_usage; + if (getrusage(RUSAGE_SELF, &resource_usage) != 0) + { + MemUsage = "Error :("; + } + else + { + Printf(MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); + } +#else + HANDLE hProcess = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS pmc; + if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) + { + Printf(MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); + } +#endif + return MemUsage; +} diff --git a/source/WebAdmin.h b/source/WebAdmin.h index ad733e704..3e57bbf00 100644 --- a/source/WebAdmin.h +++ b/source/WebAdmin.h @@ -4,66 +4,93 @@ #include "OSSupport/Socket.h" class cStringMap; +class cLuaScript; -struct HTTPFormData // tolua_export -{ // tolua_export - std::string Name; // tolua_export - std::string Value; // tolua_export - std::string Type; // tolua_export +struct HTTPFormData // tolua_export +{ // tolua_export + std::string Name; // tolua_export + std::string Value; // tolua_export + std::string Type; // tolua_export };// tolua_export -struct HTTPRequest // tolua_export -{ // tolua_export +struct HTTPRequest // tolua_export +{ // tolua_export typedef std::map< std::string, std::string > StringStringMap; typedef std::map< std::string, HTTPFormData > FormDataMap; - std::string Method; // tolua_export - std::string Path; // tolua_export - StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << - StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << - std::string Username; // tolua_export - FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << + AString Method; // tolua_export + AString Path; // tolua_export + StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << + StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << + AString Username; // tolua_export + FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << }; // tolua_export +struct HTTPTemplateRequest // tolua_export +{ // tolua_export + HTTPRequest Request; // tolua_export + +}; // tolua_export + +// tolua_begin +struct sWebAdminPage +{ + AString Content; + AString PluginName; + AString TabName; +}; +// tolua_end + struct lua_State; class cEvent; class cIniFile; class cWebPlugin; -class cWebAdmin -{ -public: + +class cWebAdmin // tolua_export +{ // tolua_export +public: // tolua_export cWebAdmin( int a_Port = 8080 ); ~cWebAdmin(); - bool Init( int a_Port ); + bool Init( int a_Port ); - void AddPlugin( cWebPlugin* a_Plugin ); - void RemovePlugin( cWebPlugin* a_Plugin ); + void AddPlugin( cWebPlugin* a_Plugin ); + void RemovePlugin( cWebPlugin* a_Plugin ); typedef std::list< cWebPlugin* > PluginList; - PluginList GetPlugins() { return m_Plugins; } - static void Request_Handler(webserver::http_request* r); + // TODO: Convert this to the auto-locking callback mechanism used for looping players in worlds and such + PluginList GetPlugins() const { return m_Plugins; } // >> EXPORTED IN MANUALBINDINGS << - int GetPort() { return m_Port; } + static void Request_Handler(webserver::http_request* r); + + int GetPort() { return m_Port; } // tolua_export + + sWebAdminPage GetPage(const HTTPRequest& a_Request); // tolua_export + AString GetBaseURL(const AString& a_URL); // tolua_export + AString GetBaseURL(const AStringVector& a_URLSplit); + + AString GetMemoryUsage() const; // tolua_export private: #ifdef _WIN32 static DWORD WINAPI ListenThread(LPVOID lpParam); #else - static void *ListenThread( void *lpParam ); + static void * ListenThread( void *lpParam ); #endif - std::string GetTemplate(); + AString GetTemplate(); - int m_Port; + cLuaScript* m_pTemplate; - bool m_bConnected; - cSocket m_ListenSocket; + int m_Port; - cIniFile* m_IniFile; - PluginList m_Plugins; + bool m_bConnected; + cSocket m_ListenSocket; - cEvent* m_Event; + cIniFile* m_IniFile; + PluginList m_Plugins; - webserver* m_WebServer; -}; \ No newline at end of file + cEvent* m_Event; + + webserver* m_WebServer; +}; // tolua_export \ No newline at end of file diff --git a/source/WebPlugin.cpp b/source/WebPlugin.cpp index 343ca64fa..48ddb2076 100644 --- a/source/WebPlugin.cpp +++ b/source/WebPlugin.cpp @@ -59,7 +59,7 @@ std::list > cWebPlugin::GetTabNames(void) -std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(HTTPRequest * a_Request) +std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest * a_Request) { std::pair< AString, AString > Names; AStringVector Split = StringSplit(a_Request->Path, "/"); diff --git a/source/WebPlugin.h b/source/WebPlugin.h index 160c3c126..22587b892 100644 --- a/source/WebPlugin.h +++ b/source/WebPlugin.h @@ -16,10 +16,10 @@ public: cWebPlugin(); virtual ~cWebPlugin(); - virtual const AString & GetWebTitle(void) const = 0; // tolua_begin + virtual const AString GetWebTitle(void) const = 0; - virtual AString HandleWebRequest( HTTPRequest * a_Request ) = 0; + virtual AString HandleWebRequest(const HTTPRequest * a_Request ) = 0; static AString SafeString( const AString & a_String ); // tolua_end @@ -35,8 +35,9 @@ public: typedef std::list< sWebPluginTab* > TabList; TabList & GetTabs() { return m_Tabs; } - std::list< std::pair > GetTabNames(); - std::pair< AString, AString > GetTabNameForRequest( HTTPRequest* a_Request ); + typedef std::list< std::pair > TabNameList; + TabNameList GetTabNames(); // >> EXPORTED IN MANUALBINDINGS << + std::pair< AString, AString > GetTabNameForRequest(const HTTPRequest* a_Request ); private: TabList m_Tabs;