From 386d58b5862d8b76925c6523721594887606e82a Mon Sep 17 00:00:00 2001 From: faketruth Date: Mon, 3 Oct 2011 18:41:19 +0000 Subject: MCServer c++ source files git-svn-id: http://mc-server.googlecode.com/svn/trunk@3 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cWebAdmin.cpp | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 source/cWebAdmin.cpp (limited to 'source/cWebAdmin.cpp') diff --git a/source/cWebAdmin.cpp b/source/cWebAdmin.cpp new file mode 100644 index 000000000..d6881c55f --- /dev/null +++ b/source/cWebAdmin.cpp @@ -0,0 +1,309 @@ +#include "cWebAdmin.h" +#include "cMCLogger.h" +#include "cStringMap.h" + +#include "cWebPlugin.h" + +#include "cPluginManager.h" +#include "cPlugin.h" + +#include "cEvent.h" +#include "cWorld.h" +#include "cPlayer.h" +#include "cServer.h" +#include "cRoot.h" + +#include + +#include "../iniFile/iniFile.h" + +#include "MemoryLeak.h" +#ifdef _WIN32 +#include +#else +#include +#endif + +extern std::vector StringSplit(std::string str, std::string delim); + +cWebAdmin* WebAdmin = 0; + +cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) + : m_Port( a_Port ) + , m_bConnected( false ) +{ + WebAdmin = this; + m_Event = new cEvent(); + Init( m_Port ); +} + +cWebAdmin::~cWebAdmin() +{ + WebAdmin = 0; + m_WebServer->Stop(); + + while( m_Plugins.begin() != m_Plugins.end() ) + { + delete *m_Plugins.begin(); + //m_Plugins.remove( *m_Plugins.begin() ); + } + delete m_WebServer; + delete m_IniFile; + + m_Event->Wait(); + delete m_Event; +} + +void ReplaceString( std::string & a_HayStack, const std::string & a_Needle, const std::string & a_ReplaceWith ) +{ + size_t pos1 = a_HayStack.find( a_Needle ); + a_HayStack.replace( pos1, a_Needle.size(), a_ReplaceWith ); +} + +void cWebAdmin::AddPlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); + m_Plugins.push_back( a_Plugin ); +} + +void cWebAdmin::RemovePlugin( cWebPlugin* a_Plugin ) +{ + m_Plugins.remove( a_Plugin ); +} + +void cWebAdmin::Request_Handler(webserver::http_request* r) +{ + if( WebAdmin == 0 ) return; + LOG("Path: %s", r->path_.c_str() ); + + std::vector< std::string > Split = StringSplit( r->path_, "/" ); + + if(r->path_ == "/") + { + r->answer_ += "
"; + r->answer_ += "MCServer WebAdmin"; + r->answer_ += "
"; + r->answer_ += "
"; + r->answer_ += ""; + r->answer_ += "
"; + r->answer_ += "
"; + return; + } + else if( Split.size() > 0 && Split[0] == "webadmin" ) + { + if( r->authentication_given_ ) + { + std::string UserPassword = WebAdmin->m_IniFile->GetValue( "User:"+r->username_, "Password", ""); + if (UserPassword != "" && r->password_ == UserPassword) + { + std::string Menu; + std::string Content; + std::string Template = WebAdmin->GetTemplate(); + + Content += "

Current Game

"; + Content += "

Server Name:

"; + Content += "

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

"; + + Content += "

Plugins:

"; + cPluginManager* PM = cRoot::Get()->GetPluginManager(); + const cPluginManager::PluginList & List = PM->GetAllPlugins(); + for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr ) + { + Content += (*itr)->GetName() + "
"; + } + Content += "

"; + Content += "

Players:

"; + + cWorld* World = cRoot::Get()->GetWorld(); + cWorld::PlayerList PlayerList = World->GetAllPlayers(); + for( cWorld::PlayerList::iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr ) + { + Content += std::string( (*itr)->GetName() ) + "
"; + } + Content += "

"; + + for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) + { + Menu += "
  • " + (*itr)->GetName() + "
  • "; + } + + HTTPRequest Request; + Request.Username = r->username_; + Request.Method = r->method_; + Request.Params = new cStringMap(r->params_); + Request.Path = r->path_; + + if( Split.size() > 1 ) + { + std::string FoundPlugin = ""; + for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) + { + if( (*itr)->GetName() == Split[1] ) + { + Content = (*itr)->HandleRequest( &Request ); + FoundPlugin = (*itr)->GetName(); + break; + } + } + + if( FoundPlugin.compare("") != 0 ) // Add some header + { + Content = "

    " + FoundPlugin + "

    \n

    " + Content + "

    "; + } + } + + delete Request.Params; + + if( Split.size() > 1 ) + { + Content += "\n

    Go back

    "; + } + + // mem usage +#ifndef _WIN32 + rusage resource_usage; + if (getrusage(RUSAGE_SELF, &resource_usage) != 0) + { + ReplaceString( Template, std::string("{MEM}"), "Error :(" ); + } + else + { + char MemUsage[32]; + sprintf( MemUsage, "%0.2f", ((double)resource_usage.ru_maxrss / 1024 / 1024) ); + ReplaceString( Template, std::string("{MEM}"), MemUsage ); + } +#else + HANDLE hProcess = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS pmc; + if( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc) ) ) + { + char MemUsage[32]; + sprintf( MemUsage, "%0.2f", (pmc.WorkingSetSize / 1024.f / 1024.f) ); + ReplaceString( Template, std::string("{MEM}"), MemUsage ); + } +#endif + // end mem usage + + ReplaceString( Template, std::string("{USERNAME}"), r->username_ ); + ReplaceString( Template, std::string("{MENU}"), Menu ); + ReplaceString( Template, std::string("{CONTENT}"), Content ); + ReplaceString( Template, std::string("{TITLE}"), "MCServer" ); + + r->answer_ = Template; + } + else + { + r->answer_ += "Wrong username/password"; + r->auth_realm_ = "MCServer WebAdmin"; + } + } + else + { + r->answer_ += "no auth"; + r->auth_realm_ = "MCServer WebAdmin"; + } + } +} + +bool cWebAdmin::Init( int a_Port ) +{ + m_Port = a_Port; + + m_IniFile = new cIniFile("webadmin.ini"); + if( m_IniFile->ReadFile() ) + { + m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); + } + + LOG("Starting WebAdmin on port %i", m_Port); + +#ifdef _WIN32 + HANDLE hThread = CreateThread( + NULL, // default security + 0, // default stack size + ListenThread, // name of the thread function + this, // thread parameters + 0, // default startup flags + NULL); + CloseHandle( hThread ); // Just close the handle immediately +#else + pthread_t LstnThread; + pthread_create( &LstnThread, 0, ListenThread, this); +#endif + + return true; +} + +#ifdef _WIN32 +DWORD WINAPI cWebAdmin::ListenThread(LPVOID lpParam) +#else +void *cWebAdmin::ListenThread( void *lpParam ) +#endif +{ + cWebAdmin* self = (cWebAdmin*)lpParam; + + self->m_WebServer = new webserver(self->m_Port, Request_Handler ); + self->m_WebServer->Begin(); + + self->m_Event->Set(); + return 0; +} + +std::string cWebAdmin::GetTemplate() +{ + std::string retVal = ""; + + char SourceFile[] = "webadmin/template.html"; + + FILE* f; +#ifdef _WIN32 + if( fopen_s(&f, SourceFile, "rb" ) == 0 ) // no error +#else + if( (f = fopen(SourceFile, "rb" ) ) != 0 ) // no error +#endif + { + // obtain file size: + fseek (f , 0 , SEEK_END); + long lSize = ftell (f); + rewind (f); + + // allocate memory to contain the whole file: + char* buffer = (char*) malloc (sizeof(char)*lSize); + + // copy the file into the buffer: + size_t result = fread (buffer, 1, lSize, f); + if ((long)result != lSize) + { + LOG ("WEBADMIN: Could not read file %s", SourceFile); + free( buffer ); + return ""; + } + + retVal.assign( buffer, lSize ); + + free( buffer ); + fclose(f); + } + return retVal; +} + + +void cWebAdmin::RemovePlugin( lua_State* L ) +{ + for( PluginList::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ) + { + if( (*itr)->GetLuaState() == L ) + { + PluginList::iterator prev = itr++; + delete *prev; // deleting a dereferenced iterator also takes it out of the list, so no need for erase() + } + else + ++itr; + } +} -- cgit v1.2.3