From eb9d45e9065a94c93dc2f1624c22f026b9be3d5f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 19:18:06 +0200 Subject: Moved MaxPlayers and Description from cWorld to cServer. Also started creating a new cWorld::cTickThread class, but not used yet. --- source/Bindings.cpp | 235 +++++++++++++++++++-------------- source/Bindings.h | 2 +- source/ClientHandle.cpp | 14 +- source/Protocol/ProtocolRecognizer.cpp | 17 +-- source/Server.cpp | 64 +++++---- source/Server.h | 17 ++- source/World.cpp | 73 ++++++---- source/World.h | 38 +++--- 8 files changed, 274 insertions(+), 186 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index fb532b6f2..ca6b42902 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 14:53:45. +** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37. */ #ifndef __cplusplus @@ -11306,6 +11306,135 @@ static int tolua_get_cPlugin_NewLua___cWebPlugin__(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetDescription of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetDescription00 +static int tolua_AllToLua_cServer_GetDescription00(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 'GetDescription'", NULL); +#endif + { + const AString tolua_ret = (const AString) self->GetDescription(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetDescription'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxPlayers of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetMaxPlayers00 +static int tolua_AllToLua_cServer_GetMaxPlayers00(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 'GetMaxPlayers'", NULL); +#endif + { + int tolua_ret = (int) self->GetMaxPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNumPlayers of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetNumPlayers00 +static int tolua_AllToLua_cServer_GetNumPlayers00(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 'GetNumPlayers'", NULL); +#endif + { + int tolua_ret = (int) self->GetNumPlayers(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetMaxPlayers of class cServer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SetMaxPlayers00 +static int tolua_AllToLua_cServer_SetMaxPlayers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); + int a_MaxPlayers = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL); +#endif + { + self->SetMaxPlayers(a_MaxPlayers); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: BroadcastChat of class cServer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_BroadcastChat00 static int tolua_AllToLua_cServer_BroadcastChat00(lua_State* tolua_S) @@ -11954,103 +12083,6 @@ static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: GetMaxPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetMaxPlayers00 -static int tolua_AllToLua_cWorld_GetMaxPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxPlayers'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetMaxPlayers(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetMaxPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetMaxPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SetMaxPlayers00 -static int tolua_AllToLua_cWorld_SetMaxPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - int iMax = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMaxPlayers'", NULL); -#endif - { - self->SetMaxPlayers(iMax); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetMaxPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetNumPlayers of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumPlayers00 -static int tolua_AllToLua_cWorld_GetNumPlayers00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL); -#endif - { - unsigned int tolua_ret = (unsigned int) self->GetNumPlayers(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetNumPlayers'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: RegenerateChunk of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_RegenerateChunk00 static int tolua_AllToLua_cWorld_RegenerateChunk00(lua_State* tolua_S) @@ -29783,6 +29815,10 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cServer","cServer","",NULL); tolua_beginmodule(tolua_S,"cServer"); + tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00); + tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cServer_GetMaxPlayers00); + tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cServer_GetNumPlayers00); + tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cServer_SetMaxPlayers00); 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); @@ -29806,9 +29842,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetDimension",tolua_AllToLua_cWorld_GetDimension00); tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00); tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00); - tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cWorld_GetMaxPlayers00); - tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cWorld_SetMaxPlayers00); - tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cWorld_GetNumPlayers00); tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00); tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00); tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00); diff --git a/source/Bindings.h b/source/Bindings.h index ec1e372f7..d80c98782 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 14:53:46. +** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 102153de1..14b052652 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -421,11 +421,11 @@ void cClientHandle::HandlePing(void) // Somebody tries to retrieve information about the server AString Reply; Printf(Reply, "%s%s%i%s%i", - cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + cRoot::Get()->GetServer()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetServer()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetServer()->GetMaxPlayers() ); Kick(Reply.c_str()); } @@ -1176,7 +1176,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) { if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(this, a_Username)) { - if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()) + if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) { Kick("The server is currently full :(-- Try again later"); return false; @@ -1191,7 +1191,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) void cClientHandle::HandleEntityAction(int a_EntityID, char a_ActionID) { - if( a_EntityID != m_Player->GetUniqueID() ) + if (a_EntityID != m_Player->GetUniqueID()) { // We should only receive entity actions from the entity that is performing the action return; diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index 290f2df75..35c8fe993 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -14,6 +14,7 @@ #include "Protocol16x.h" #include "../ClientHandle.h" #include "../Root.h" +#include "../Server.h" #include "../World.h" #include "../ChatColor.h" @@ -729,11 +730,11 @@ void cProtocolRecognizer::HandleServerPing(void) { // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 Printf(Reply, "%s%s%i%s%i", - cRoot::Get()->GetDefaultWorld()->GetDescription().c_str(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetNumPlayers(), - cChatColor::Delimiter.c_str(), - cRoot::Get()->GetDefaultWorld()->GetMaxPlayers() + cRoot::Get()->GetServer()->GetDescription().c_str(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetServer()->GetNumPlayers(), + cChatColor::Delimiter.c_str(), + cRoot::Get()->GetServer()->GetMaxPlayers() ); break; } @@ -759,9 +760,9 @@ void cProtocolRecognizer::HandleServerPing(void) // http://wiki.vg/wiki/index.php?title=Server_List_Ping&oldid=3100 AString NumPlayers; - Printf(NumPlayers, "%d", cRoot::Get()->GetDefaultWorld()->GetNumPlayers()); + Printf(NumPlayers, "%d", cRoot::Get()->GetServer()->GetNumPlayers()); AString MaxPlayers; - Printf(MaxPlayers, "%d", cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()); + Printf(MaxPlayers, "%d", cRoot::Get()->GetServer()->GetMaxPlayers()); AString ProtocolVersionNum; Printf(ProtocolVersionNum, "%d", cRoot::Get()->m_PrimaryServerVersion); @@ -775,7 +776,7 @@ void cProtocolRecognizer::HandleServerPing(void) Reply.push_back(0); Reply.append(ProtocolVersionTxt); Reply.push_back(0); - Reply.append(cRoot::Get()->GetDefaultWorld()->GetDescription()); + Reply.append(cRoot::Get()->GetServer()->GetDescription()); Reply.push_back(0); Reply.append(NumPlayers); Reply.push_back(0); diff --git a/source/Server.cpp b/source/Server.cpp index b07c65f04..509c84af3 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -76,6 +76,38 @@ struct cServer::sServerState +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cServer: + +cServer::cServer(void) : + m_pState(new sServerState), + m_ListenThreadIPv4(*this, cSocket::IPv4, "Client"), + m_ListenThreadIPv6(*this, cSocket::IPv6, "Client"), + m_Millisecondsf(0), + m_Milliseconds(0), + m_bIsConnected(false), + m_bRestarting(false), + m_RCONServer(*this) +{ +} + + + + + +cServer::~cServer() +{ + // TODO: Shut down the server gracefully + m_pState->bStopTickThread = true; + delete m_pState->pTickThread; m_pState->pTickThread = NULL; + + delete m_pState; +} + + + + + void cServer::ClientDestroying(const cClientHandle * a_Client) { m_SocketThreads.StopReading(a_Client); @@ -123,6 +155,9 @@ void cServer::RemoveClient(const cClientHandle * a_Client) bool cServer::InitServer(cIniFile & a_SettingsIni) { + m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str(); + m_MaxPlayers = a_SettingsIni.GetValueI("Server", "MaxPlayers", 100); + if (m_bIsConnected) { LOGERROR("ERROR: Trying to initialize server while server is already running!"); @@ -201,35 +236,6 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) -cServer::cServer(void) - : m_pState(new sServerState) - , m_ListenThreadIPv4(*this, cSocket::IPv4, "Client") - , m_ListenThreadIPv6(*this, cSocket::IPv6, "Client") - , m_Millisecondsf(0) - , m_Milliseconds(0) - , m_bIsConnected(false) - , m_bRestarting(false) - , m_RCONServer(*this) -{ -} - - - - - -cServer::~cServer() -{ - // TODO: Shut down the server gracefully - m_pState->bStopTickThread = true; - delete m_pState->pTickThread; m_pState->pTickThread = NULL; - - delete m_pState; -} - - - - - void cServer::PrepareKeys(void) { // TODO: Save and load key for persistence across sessions diff --git a/source/Server.h b/source/Server.h index dd7a08735..44e20eec1 100644 --- a/source/Server.h +++ b/source/Server.h @@ -37,7 +37,18 @@ class cServer // tolua_export public: // tolua_export bool InitServer(cIniFile & a_SettingsIni); - bool IsConnected(void) const { return m_bIsConnected;} // returns connection status + // tolua_begin + + const AString & GetDescription(void) const {return m_Description; } + + // Player counts: + int GetMaxPlayers(void) const {return m_MaxPlayers; } + int GetNumPlayers(void) const { return m_NumPlayers; } + void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } + + // tolua_end + + // bool IsConnected(void) const { return m_bIsConnected;} // returns connection status void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export @@ -131,6 +142,10 @@ private: cRCONServer m_RCONServer; + AString m_Description; + int m_MaxPlayers; + int m_NumPlayers; + cServer(void); ~cServer(); diff --git a/source/World.cpp b/source/World.cpp index 776bacff8..ebfee971b 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -128,6 +128,9 @@ protected: +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorldLightingProgress: + /// A simple thread that displays the progress of world lighting in cWorld::InitializeSpawn() class cWorldLightingProgress : public cIsThread @@ -187,10 +190,46 @@ cWorld::cLock::cLock(cWorld & a_World) : +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld::cTickThread: + +cWorld::cTickThread::cTickThread(cWorld & a_World) : + super(Printf("WorldTickThread: %s", a_World.GetName().c_str())), + m_World(a_World) +{ +} + + + + + +void cWorld::cTickThread::Execute(void) +{ + const int ClocksPerTick = CLOCKS_PER_SEC / 20; + clock_t LastTime = clock(); + while (!m_ShouldTerminate) + { + clock_t Start = clock(); + m_World.Tick((float)(LastTime - Start) / CLOCKS_PER_SEC); + clock_t Now = clock(); + if (Now - Start < ClocksPerTick) + { + cSleep::MilliSleep(1000 * (ClocksPerTick - (Now - Start)) / CLOCKS_PER_SEC); + } + LastTime = Start; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cWorld: cWorld::cWorld(const AString & a_WorldName) : + m_WorldName(a_WorldName), + m_IniFileName(m_WorldName + "/world.ini"), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -199,24 +238,26 @@ cWorld::cWorld(const AString & a_WorldName) : m_LastSpawnMonster(0), m_RSList(0), m_Weather(eWeather_Sunny), - m_WeatherInterval(24000) // Guaranteed 1 day of sunshine at server start :) + m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) + m_TickThread(*this) { LOGD("cWorld::cWorld(%s)", a_WorldName.c_str()); - m_WorldName = a_WorldName; - m_IniFileName = m_WorldName + "/world.ini"; cMakeDir::MakeDir(m_WorldName.c_str()); - MTRand r1; - m_SpawnX = (double)((r1.randInt() % 1000) - 500); + // TODO: Find a proper spawn location, based on the biomes (not in ocean) + m_SpawnX = (double)((m_TickRand.randInt() % 1000) - 500); m_SpawnY = cChunkDef::Height; - m_SpawnZ = (double)((r1.randInt() % 1000) - 500); + m_SpawnZ = (double)((m_TickRand.randInt() % 1000) - 500); m_GameMode = eGameMode_Creative; AString StorageSchema("Default"); cIniFile IniFile(m_IniFileName); - IniFile.ReadFile(); + if (!IniFile.ReadFile()) + { + LOGWARNING("Cannot read world settings from \"%s\", defaults will be used.", m_IniFileName.c_str()); + } AString Dimension = IniFile.GetValueSet("General", "Dimension", "Overworld"); m_Dimension = StringToDimension(Dimension); switch (m_Dimension) @@ -268,9 +309,6 @@ cWorld::cWorld(const AString & a_WorldName) : m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true); m_SpawnMonsterRate = (Int64)(IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10) * 20); // Convert from secs to ticks - // TODO: Move this into cServer instead: - SetMaxPlayers(IniFile2.GetValueI("Server", "MaxPlayers", 100)); - m_Description = IniFile2.GetValue("Server", "Description", "MCServer! - In C++!").c_str(); } m_ChunkMap = new cChunkMap(this); @@ -1893,19 +1931,6 @@ void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) -void cWorld::SetMaxPlayers(int iMax) -{ - m_MaxPlayers = MAX_PLAYERS; - if (iMax > 0 && iMax < MAX_PLAYERS) - { - m_MaxPlayers = iMax; - } -} - - - - - void cWorld::AddPlayer(cPlayer * a_Player) { cCSLock Lock(m_CSPlayers); @@ -2299,11 +2324,13 @@ void cWorld::RemoveEntity(cEntity * a_Entity) +/* unsigned int cWorld::GetNumPlayers(void) { cCSLock Lock(m_CSPlayers); return m_Players.size(); } +*/ diff --git a/source/World.h b/source/World.h index b9182e300..1ae56a410 100644 --- a/source/World.h +++ b/source/World.h @@ -204,13 +204,6 @@ public: void CollectPickupsByPlayer(cPlayer * a_Player); - // MOTD - const AString & GetDescription(void) const {return m_Description; } // FIXME: This should not be in cWorld - - // Max Players - unsigned int GetMaxPlayers(void) const {return m_MaxPlayers; } // tolua_export - void SetMaxPlayers(int iMax); // tolua_export - void AddPlayer( cPlayer* a_Player ); void RemovePlayer( cPlayer* a_Player ); @@ -223,8 +216,6 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - unsigned int GetNumPlayers(); // tolua_export - // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit); @@ -484,8 +475,6 @@ public: inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export - void Tick(float a_Dt); - void InitializeSpawn(void); /// Stops threads that belong to this world (part of deinit) @@ -540,7 +529,25 @@ public: private: friend class cRoot; + + class cTickThread : + public cIsThread + { + typedef cIsThread super; + public: + cTickThread(cWorld & a_World); + + protected: + cWorld & m_World; + + // cIsThread overrides: + virtual void Execute(void) override; + } ; + + AString m_WorldName; + AString m_IniFileName; + /// The dimension of the world, used by the client to provide correct lighting scheme eDimension m_Dimension; @@ -583,8 +590,6 @@ private: cWorldStorage m_Storage; - AString m_Description; - unsigned int m_MaxPlayers; cChunkMap * m_ChunkMap; @@ -616,13 +621,14 @@ private: cChunkSender m_ChunkSender; cLightingThread m_Lighting; + cTickThread m_TickThread; + - AString m_WorldName; - AString m_IniFileName; - cWorld(const AString & a_WorldName); ~cWorld(); + void Tick(float a_Dt); + void TickWeather(float a_Dt); // Handles weather each tick void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick -- cgit v1.2.3 From 2baa6634ec797d4a64c25fca9b5a0451b69bf886 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 19:40:15 +0200 Subject: cIsThread: Added the Stop() method and debugging output in Wait() --- source/OSSupport/IsThread.cpp | 44 ++++++++++++++++++++++--------------------- source/OSSupport/IsThread.h | 4 +++- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/source/OSSupport/IsThread.cpp b/source/OSSupport/IsThread.cpp index 257c5c876..45e329a68 100644 --- a/source/OSSupport/IsThread.cpp +++ b/source/OSSupport/IsThread.cpp @@ -116,36 +116,38 @@ bool cIsThread::Start(void) +void cIsThread::Stop(void) +{ + if (m_Handle == NULL) + { + return; + } + m_ShouldTerminate = true; + Wait(); +} + + + + + bool cIsThread::Wait(void) { - #ifdef _WIN32 + if (m_Handle == NULL) + { + return true; + } + LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); - if (m_Handle == NULL) - { - return true; - } - // Cannot log, logger may already be stopped: - // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); + #ifdef _WIN32 int res = WaitForSingleObject(m_Handle, INFINITE); m_Handle = NULL; - // Cannot log, logger may already be stopped: - // LOG("Thread \"%s\" %s terminated, GLE = %d", m_ThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError()); + LOGD("Thread %s finished", m_ThreadName.c_str()); return (res == WAIT_OBJECT_0); - #else // _WIN32 - - if (!m_HasStarted) - { - return true; - } - // Cannot log, logger may already be stopped: - // LOG("Waiting for thread \"%s\" to terminate.", m_ThreadName.c_str()); int res = pthread_join(m_Handle, NULL); - m_HasStarted = false; - // Cannot log, logger may already be stopped: - // LOG("Thread \"%s\" %s terminated, errno = %d", m_ThreadName.c_str(), (res == 0) ? "" : "not", errno); + m_Handle = NULL; + LOGD("Thread %s finished", m_ThreadName.c_str()); return (res == 0); - #endif // else _WIN32 } diff --git a/source/OSSupport/IsThread.h b/source/OSSupport/IsThread.h index 2a4451a4a..e795b25a0 100644 --- a/source/OSSupport/IsThread.h +++ b/source/OSSupport/IsThread.h @@ -39,6 +39,9 @@ public: /// Starts the thread; returns without waiting for the actual start bool Start(void); + /// Signals the thread to terminate and waits until it's finished + void Stop(void); + /// Waits for the thread to finish. Doesn't signalize the ShouldTerminate flag bool Wait(void); @@ -70,7 +73,6 @@ private: } #endif // else _WIN32 - } ; -- cgit v1.2.3 From c59d80a2af12d902577ea8cb022e81dd0740247f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 19:46:27 +0200 Subject: Removed cServer::m_pState, dissolved into direct member variables. The server tick thread is now in the cServer::cTickThread object. --- source/Server.cpp | 141 +++++++++++++++++++----------------------------------- source/Server.h | 35 ++++++++++---- 2 files changed, 75 insertions(+), 101 deletions(-) diff --git a/source/Server.cpp b/source/Server.cpp index 509c84af3..4247a1dfe 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -59,18 +59,42 @@ typedef std::list< cClientHandle* > ClientList; -struct cServer::sServerState +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cServer::cTickThread: + +cServer::cTickThread::cTickThread(cServer & a_Server) : + super("ServerTickThread"), + m_Server(a_Server) +{ +} + + + + + +void cServer::cTickThread::Execute(void) { - sServerState() - : pTickThread(NULL) - , bStopTickThread(false) - {} + cTimer Timer; - cThread* pTickThread; bool bStopTickThread; + long long msPerTick = 50; // TODO - Put this in server config file + long long LastTime = Timer.GetNowTime(); + + while (!m_ShouldTerminate) + { + long long NowTime = Timer.GetNowTime(); + float DeltaTime = (float)(NowTime-LastTime); + m_ShouldTerminate = !m_Server.Tick(DeltaTime); + long long TickTime = Timer.GetNowTime() - NowTime; + + if (TickTime < msPerTick) + { + // Stretch tick time until it's at least msPerTick + cSleep::MilliSleep((unsigned int)(msPerTick - TickTime)); + } - cEvent RestartEvent; - std::string ServerID; -}; + LastTime = NowTime; + } +} @@ -80,28 +104,13 @@ struct cServer::sServerState // cServer: cServer::cServer(void) : - m_pState(new sServerState), m_ListenThreadIPv4(*this, cSocket::IPv4, "Client"), m_ListenThreadIPv6(*this, cSocket::IPv6, "Client"), - m_Millisecondsf(0), - m_Milliseconds(0), m_bIsConnected(false), m_bRestarting(false), - m_RCONServer(*this) -{ -} - - - - - -cServer::~cServer() + m_RCONServer(*this), + m_TickThread(*this) { - // TODO: Shut down the server gracefully - m_pState->bStopTickThread = true; - delete m_pState->pTickThread; m_pState->pTickThread = NULL; - - delete m_pState; } @@ -199,18 +208,17 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) m_bIsConnected = true; - m_pState->ServerID = "-"; + m_ServerID = "-"; if (a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true)) { MTRand mtrand1; - unsigned int r1 = (mtrand1.randInt()%1147483647) + 1000000000; - unsigned int r2 = (mtrand1.randInt()%1147483647) + 1000000000; + unsigned int r1 = (mtrand1.randInt() % 1147483647) + 1000000000; + unsigned int r2 = (mtrand1.randInt() % 1147483647) + 1000000000; std::ostringstream sid; sid << std::hex << r1; sid << std::hex << r2; - std::string ServerID = sid.str(); - ServerID.resize(16, '0'); - m_pState->ServerID = ServerID; + m_ServerID = sid.str(); + m_ServerID.resize(16, '0'); } m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE); @@ -309,15 +317,8 @@ void cServer::BroadcastChat(const AString & a_Message, const cClientHandle * a_E bool cServer::Tick(float a_Dt) { - m_Millisecondsf += a_Dt; - if (m_Millisecondsf > 1.f) - { - m_Milliseconds += (int)m_Millisecondsf; - m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf; - } - - cRoot::Get()->TickWorlds(a_Dt); // TODO - Maybe give all worlds their own thread? - + cRoot::Get()->TickWorlds(a_Dt); + cClientHandleList RemoveClients; { cCSLock Lock(m_CSClients); @@ -338,8 +339,6 @@ bool cServer::Tick(float a_Dt) delete *itr; } // for itr - RemoveClients[] - cRoot::Get()->GetPluginManager()->Tick(a_Dt); - if (!m_bRestarting) { return true; @@ -347,7 +346,7 @@ bool cServer::Tick(float a_Dt) else { m_bRestarting = false; - m_pState->RestartEvent.Set(); + m_RestartEvent.Set(); return false; } } @@ -356,42 +355,8 @@ bool cServer::Tick(float a_Dt) -void ServerTickThread( void * a_Param ) -{ - LOG("ServerTickThread"); - cServer *CServerObj = (cServer*)a_Param; - - cTimer Timer; - - long long msPerTick = 50; // TODO - Put this in server config file - long long LastTime = Timer.GetNowTime(); - - bool bKeepGoing = true; - while( bKeepGoing ) - { - long long NowTime = Timer.GetNowTime(); - float DeltaTime = (float)(NowTime-LastTime); - bKeepGoing = CServerObj->Tick( DeltaTime ); - long long TickTime = Timer.GetNowTime() - NowTime; - - if( TickTime < msPerTick ) // Stretch tick time until it's at least msPerTick - { - cSleep::MilliSleep( (unsigned int)( msPerTick - TickTime ) ); - } - - LastTime = NowTime; - } - - LOG("TICK THREAD STOPPED"); -} - - - - - bool cServer::Start(void) { - m_pState->pTickThread = new cThread( ServerTickThread, this, "cServer::ServerTickThread" ); if (!m_ListenThreadIPv4.Start()) { return false; @@ -400,7 +365,10 @@ bool cServer::Start(void) { return false; } - m_pState->pTickThread->Start( true ); + if (!m_TickThread.Start()) + { + return false; + } return true; } @@ -503,13 +471,13 @@ void cServer::SendMessage(const AString & a_Message, cPlayer * a_Player /* = NUL -void cServer::Shutdown() +void cServer::Shutdown(void) { m_ListenThreadIPv4.Stop(); m_ListenThreadIPv6.Stop(); m_bRestarting = true; - m_pState->RestartEvent.Wait(); + m_RestartEvent.Wait(); cRoot::Get()->SaveAllChunks(); @@ -526,15 +494,6 @@ void cServer::Shutdown() -const AString & cServer::GetServerID(void) const -{ - return m_pState->ServerID; -} - - - - - void cServer::KickUser(int a_ClientID, const AString & a_Reason) { cCSLock Lock(m_CSClients); @@ -568,7 +527,7 @@ void cServer::AuthenticateUser(int a_ClientID) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cServer::cClientPacketThread: +// cServer::cNotifyWriteThread: cServer::cNotifyWriteThread::cNotifyWriteThread(void) : super("ClientPacketThread"), diff --git a/source/Server.h b/source/Server.h index 44e20eec1..983dc4de8 100644 --- a/source/Server.h +++ b/source/Server.h @@ -52,8 +52,6 @@ public: // tolua_export void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export - bool Tick(float a_Dt); - bool Start(void); bool Command(cClientHandle & a_Client, AString & a_Cmd); @@ -71,7 +69,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; // tolua_export + const AString & GetServerID(void) const { return m_ServerID; } // tolua_export void ClientDestroying(const cClientHandle * a_Client); // Called by cClientHandle::Destroy(); stop m_SocketThreads from calling back into a_Client @@ -114,8 +112,22 @@ private: void NotifyClientWrite(const cClientHandle * a_Client); } ; - struct sServerState; - sServerState * m_pState; + /// The server tick thread takes care of the players who aren't yet spawned in a world + class cTickThread : + public cIsThread + { + typedef cIsThread super; + + public: + cTickThread(cServer & a_Server); + + protected: + cServer & m_Server; + + // cIsThread overrides: + virtual void Execute(void) override; + } ; + cNotifyWriteThread m_NotifyWriteThread; @@ -129,10 +141,6 @@ private: int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini - // Time since server was started - float m_Millisecondsf; - unsigned int m_Milliseconds; - bool m_bIsConnected; // true - connected false - not connected bool m_bRestarting; @@ -146,13 +154,20 @@ private: int m_MaxPlayers; int m_NumPlayers; + cTickThread m_TickThread; + cEvent m_RestartEvent; + + /// The server ID used for client authentication + AString m_ServerID; + cServer(void); - ~cServer(); /// Loads, or generates, if missing, RSA keys for protocol encryption void PrepareKeys(void); + bool Tick(float a_Dt); + // cListenThread::cCallback overrides: virtual void OnConnectionAccepted(cSocket & a_Socket) override; }; // tolua_export -- cgit v1.2.3 From 4c5590636cf4a311f03e735878557b1e7b3362dd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 20:16:41 +0200 Subject: Each world now ticks in a separate thread. --- source/Root.cpp | 15 +-- source/Root.h | 5 +- source/Server.cpp | 2 +- source/Server.h | 2 +- source/World.cpp | 204 ++++++++++++++++++----------------- source/World.h | 9 +- source/WorldStorage/WorldStorage.cpp | 9 ++ source/WorldStorage/WorldStorage.h | 1 + 8 files changed, 135 insertions(+), 112 deletions(-) diff --git a/source/Root.cpp b/source/Root.cpp index 5ec27aa0d..166932cf2 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -270,8 +270,9 @@ void cRoot::LoadWorlds(void) void cRoot::StartWorlds(void) { - for( WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr ) + for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) { + itr->second->Start(); itr->second->InitializeSpawn(); } } @@ -282,9 +283,9 @@ void cRoot::StartWorlds(void) void cRoot::StopWorlds(void) { - for( WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr ) + for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) { - itr->second->StopThreads(); + itr->second->Stop(); } } @@ -344,7 +345,7 @@ bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) -void cRoot::TickWorlds(float a_Dt) +void cRoot::TickCommands(void) { // Execute any pending commands: cCommandQueue PendingCommands; @@ -356,12 +357,6 @@ void cRoot::TickWorlds(float a_Dt) { ExecuteConsoleCommand(itr->m_Command, *(itr->m_Output)); } - - // Tick the worlds: - for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) - { - itr->second->Tick(a_Dt); - } } diff --git a/source/Root.h b/source/Root.h index 1e2befcd4..262c9b0e5 100644 --- a/source/Root.h +++ b/source/Root.h @@ -85,9 +85,10 @@ public: /// Called by cAuthenticator to auth the specified user void AuthenticateUser(int a_ClientID); - - void TickWorlds(float a_Dt); + /// Executes commands queued in the command queue + void TickCommands(void); + /// Returns the number of chunks loaded int GetTotalChunkCount(void); // tolua_export diff --git a/source/Server.cpp b/source/Server.cpp index 4247a1dfe..0045d4808 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -317,7 +317,7 @@ void cServer::BroadcastChat(const AString & a_Message, const cClientHandle * a_E bool cServer::Tick(float a_Dt) { - cRoot::Get()->TickWorlds(a_Dt); + cRoot::Get()->TickCommands(); cClientHandleList RemoveClients; { diff --git a/source/Server.h b/source/Server.h index 983dc4de8..a00485fa2 100644 --- a/source/Server.h +++ b/source/Server.h @@ -62,7 +62,7 @@ public: // tolua_export /// Binds the built-in console commands with the plugin manager static void BindBuiltInConsoleCommands(void); - void Shutdown(); + void Shutdown(void); void SendMessage(const AString & a_Message, cPlayer * a_Player = NULL, bool a_bExclude = false ); // tolua_export diff --git a/source/World.cpp b/source/World.cpp index ebfee971b..af66d1ead 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -230,6 +230,7 @@ void cWorld::cTickThread::Execute(void) cWorld::cWorld(const AString & a_WorldName) : m_WorldName(a_WorldName), m_IniFileName(m_WorldName + "/world.ini"), + m_StorageSchema("Default"), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -244,102 +245,6 @@ cWorld::cWorld(const AString & a_WorldName) : LOGD("cWorld::cWorld(%s)", a_WorldName.c_str()); cMakeDir::MakeDir(m_WorldName.c_str()); - - // TODO: Find a proper spawn location, based on the biomes (not in ocean) - m_SpawnX = (double)((m_TickRand.randInt() % 1000) - 500); - m_SpawnY = cChunkDef::Height; - m_SpawnZ = (double)((m_TickRand.randInt() % 1000) - 500); - m_GameMode = eGameMode_Creative; - - AString StorageSchema("Default"); - - cIniFile IniFile(m_IniFileName); - if (!IniFile.ReadFile()) - { - LOGWARNING("Cannot read world settings from \"%s\", defaults will be used.", m_IniFileName.c_str()); - } - AString Dimension = IniFile.GetValueSet("General", "Dimension", "Overworld"); - m_Dimension = StringToDimension(Dimension); - switch (m_Dimension) - { - case dimNether: - case dimOverworld: - case dimEnd: - { - break; - } - default: - { - LOGWARNING("Unknown dimension: \"%s\". Setting to Overworld", Dimension.c_str()); - m_Dimension = dimOverworld; - break; - } - } // switch (m_Dimension) - m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); - m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); - m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); - StorageSchema = IniFile.GetValueSet ("Storage", "Schema", StorageSchema); - m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); - m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); - m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); - m_IsCarrotsBonemealable = IniFile.GetValueSetB("Plants", "IsCarrotsBonemealable", true); - m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); - m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); - m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); - m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); - m_IsPotatoesBonemealable = IniFile.GetValueSetB("Plants", "IsPotatoesBonemealable", true); - m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); - m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); - m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); - m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); - m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true); - m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false); - - m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); - - m_Lighting.Start(this); - m_Storage.Start(this, StorageSchema); - m_Generator.Start(this, IniFile); - - m_bAnimals = true; - m_SpawnMonsterRate = 200; // 1 mob each 10 seconds - cIniFile IniFile2("settings.ini"); - if (IniFile2.ReadFile()) - { - m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true); - m_SpawnMonsterRate = (Int64)(IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10) * 20); // Convert from secs to ticks - - } - - m_ChunkMap = new cChunkMap(this); - - m_ChunkSender.Start(this); - - m_LastSave = 0; - m_LastUnload = 0; - - // preallocate some memory for ticking blocks so we don�t need to allocate that often - m_BlockTickQueue.reserve(1000); - m_BlockTickQueueCopy.reserve(1000); - - // Simulators: - m_SimulatorManager = new cSimulatorManager(*this); - m_WaterSimulator = InitializeFluidSimulator(IniFile, "Water", E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); - m_LavaSimulator = InitializeFluidSimulator(IniFile, "Lava", E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); - m_SandSimulator = new cSandSimulator(*this, IniFile); - m_FireSimulator = new cFireSimulator(*this, IniFile); - m_RedstoneSimulator = new cRedstoneSimulator(*this); - - // Water and Lava simulators get registered in InitializeFluidSimulator() - m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); - m_SimulatorManager->RegisterSimulator(m_FireSimulator, 1); - m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); - - // Save any changes that the defaults may have done to the ini file: - if (!IniFile.WriteFile()) - { - LOGWARNING("Could not write world config to %s", m_IniFileName.c_str()); - } } @@ -542,10 +447,115 @@ void cWorld::InitializeSpawn(void) -void cWorld::StopThreads(void) +void cWorld::Start(void) +{ + // TODO: Find a proper spawn location, based on the biomes (not in ocean) + m_SpawnX = (double)((m_TickRand.randInt() % 1000) - 500); + m_SpawnY = cChunkDef::Height; + m_SpawnZ = (double)((m_TickRand.randInt() % 1000) - 500); + m_GameMode = eGameMode_Creative; + + cIniFile IniFile(m_IniFileName); + if (!IniFile.ReadFile()) + { + LOGWARNING("Cannot read world settings from \"%s\", defaults will be used.", m_IniFileName.c_str()); + } + AString Dimension = IniFile.GetValueSet("General", "Dimension", "Overworld"); + m_Dimension = StringToDimension(Dimension); + switch (m_Dimension) + { + case dimNether: + case dimOverworld: + case dimEnd: + { + break; + } + default: + { + LOGWARNING("Unknown dimension: \"%s\". Setting to Overworld", Dimension.c_str()); + m_Dimension = dimOverworld; + break; + } + } // switch (m_Dimension) + m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); + m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); + m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); + m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema); + m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); + m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); + m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); + m_IsCarrotsBonemealable = IniFile.GetValueSetB("Plants", "IsCarrotsBonemealable", true); + m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); + m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); + m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); + m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); + m_IsPotatoesBonemealable = IniFile.GetValueSetB("Plants", "IsPotatoesBonemealable", true); + m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); + m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); + m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); + m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); + m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true); + m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false); + + m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); + + m_bAnimals = true; + m_SpawnMonsterRate = 200; // 1 mob each 10 seconds + cIniFile IniFile2("settings.ini"); + if (IniFile2.ReadFile()) + { + m_bAnimals = IniFile2.GetValueB("Monsters", "AnimalsOn", true); + m_SpawnMonsterRate = (Int64)(IniFile2.GetValueF("Monsters", "AnimalSpawnInterval", 10) * 20); // Convert from secs to ticks + + } + + m_ChunkMap = new cChunkMap(this); + + m_LastSave = 0; + m_LastUnload = 0; + + // preallocate some memory for ticking blocks so we don�t need to allocate that often + m_BlockTickQueue.reserve(1000); + m_BlockTickQueueCopy.reserve(1000); + + // Simulators: + m_SimulatorManager = new cSimulatorManager(*this); + m_WaterSimulator = InitializeFluidSimulator(IniFile, "Water", E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); + m_LavaSimulator = InitializeFluidSimulator(IniFile, "Lava", E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); + m_SandSimulator = new cSandSimulator(*this, IniFile); + m_FireSimulator = new cFireSimulator(*this, IniFile); + m_RedstoneSimulator = new cRedstoneSimulator(*this); + + // Water and Lava simulators get registered in InitializeFluidSimulator() + m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1); + m_SimulatorManager->RegisterSimulator(m_FireSimulator, 1); + m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); + + m_Lighting.Start(this); + m_Storage.Start(this, m_StorageSchema); + m_Generator.Start(this, IniFile); + m_ChunkSender.Start(this); + m_TickThread.Start(); + + // Save any changes that the defaults may have done to the ini file: + if (!IniFile.WriteFile()) + { + LOGWARNING("Could not write world config to %s", m_IniFileName.c_str()); + } + +} + + + + + +void cWorld::Stop(void) { + m_TickThread.Stop(); + m_Lighting.Stop(); m_Generator.Stop(); m_ChunkSender.Stop(); + m_Storage.Stop(); } diff --git a/source/World.h b/source/World.h index 1ae56a410..a12a9e40e 100644 --- a/source/World.h +++ b/source/World.h @@ -477,8 +477,12 @@ public: void InitializeSpawn(void); + /// Starts threads that belong to this world + void Start(void); + /// Stops threads that belong to this world (part of deinit) - void StopThreads(void); + void Stop(void); + void TickQueuedBlocks(float a_Dt); struct BlockTickQueueItem @@ -548,6 +552,9 @@ private: AString m_WorldName; AString m_IniFileName; + /// Name of the storage schema used to load and save chunks + AString m_StorageSchema; + /// The dimension of the world, used by the client to provide correct lighting scheme eDimension m_Dimension; diff --git a/source/WorldStorage/WorldStorage.cpp b/source/WorldStorage/WorldStorage.cpp index 8b055b240..7ff5ae8e8 100644 --- a/source/WorldStorage/WorldStorage.cpp +++ b/source/WorldStorage/WorldStorage.cpp @@ -84,6 +84,15 @@ bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName) +void cWorldStorage::Stop(void) +{ + WaitForFinish(); +} + + + + + void cWorldStorage::WaitForFinish(void) { LOG("Waiting for the world storage to finish saving"); diff --git a/source/WorldStorage/WorldStorage.h b/source/WorldStorage/WorldStorage.h index 064b2ffaf..bf8dbd3d5 100644 --- a/source/WorldStorage/WorldStorage.h +++ b/source/WorldStorage/WorldStorage.h @@ -75,6 +75,7 @@ public: void UnqueueSave(const cChunkCoords & a_Chunk); bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args + void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event void WaitForFinish(void); void WaitForQueuesEmpty(void); -- cgit v1.2.3 From ac9224da919fb642aba8dde71d1c8deaf0cc8005 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 20:22:42 +0200 Subject: cIsThread threads get a window identification on Win. This enables tools such as TaskInfo to report the thread name directly. --- source/OSSupport/IsThread.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/OSSupport/IsThread.h b/source/OSSupport/IsThread.h index e795b25a0..9b7f0b73e 100644 --- a/source/OSSupport/IsThread.h +++ b/source/OSSupport/IsThread.h @@ -57,7 +57,9 @@ private: static DWORD_PTR __stdcall thrExecute(LPVOID a_Param) { + HWND IdentificationWnd = CreateWindow("STATIC", ((cIsThread *)a_Param)->m_ThreadName.c_str(), 0, 0, 0, 0, WS_OVERLAPPED, NULL, NULL, NULL, NULL); ((cIsThread *)a_Param)->Execute(); + DestroyWindow(IdentificationWnd); return 0; } -- cgit v1.2.3 From 829cc866cd63c50ebff4dac2f942a0df93d269fc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 Aug 2013 21:05:44 +0200 Subject: Added cWorld:QueueSaveAllChunks() function for saving chunks asynchronously. The cWorld:SaveAllChunks() is therefore deprecated in the API and will be removed soon, use QueueSaveAllChunks() instead. --- source/Bindings.cpp | 34 +++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/World.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++- source/World.h | 38 ++++++++++++++++++++++++++++++++++-- 4 files changed, 125 insertions(+), 5 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index ca6b42902..46c5f0f07 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37. +** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:51. */ #ifndef __cplusplus @@ -13434,6 +13434,37 @@ static int tolua_AllToLua_cWorld_SaveAllChunks00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: QueueSaveAllChunks of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_QueueSaveAllChunks00 +static int tolua_AllToLua_cWorld_QueueSaveAllChunks00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'QueueSaveAllChunks'", NULL); +#endif + { + self->QueueSaveAllChunks(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'QueueSaveAllChunks'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetNumChunks of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetNumChunks00 static int tolua_AllToLua_cWorld_GetNumChunks00(lua_State* tolua_S) @@ -29878,6 +29909,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00); tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00); tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00); + tolua_function(tolua_S,"QueueSaveAllChunks",tolua_AllToLua_cWorld_QueueSaveAllChunks00); tolua_function(tolua_S,"GetNumChunks",tolua_AllToLua_cWorld_GetNumChunks00); tolua_function(tolua_S,"GetGeneratorQueueLength",tolua_AllToLua_cWorld_GetGeneratorQueueLength00); tolua_function(tolua_S,"GetLightingQueueLength",tolua_AllToLua_cWorld_GetLightingQueueLength00); diff --git a/source/Bindings.h b/source/Bindings.h index d80c98782..10f874e41 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 19:12:37. +** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:52. */ /* Exported function */ diff --git a/source/World.cpp b/source/World.cpp index af66d1ead..9212202e9 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BlockID.h" @@ -242,7 +243,7 @@ cWorld::cWorld(const AString & a_WorldName) : m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) m_TickThread(*this) { - LOGD("cWorld::cWorld(%s)", a_WorldName.c_str()); + LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); cMakeDir::MakeDir(m_WorldName.c_str()); } @@ -587,6 +588,7 @@ void cWorld::Tick(float a_Dt) m_ChunkMap->Tick(a_Dt); TickQueuedBlocks(a_Dt); + TickQueuedTasks(); GetSimulatorManager()->Simulate(a_Dt); @@ -781,6 +783,27 @@ void cWorld::TickSpawnMobs(float a_Dt) +void cWorld::TickQueuedTasks(void) +{ + // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks + cTasks Tasks; + { + cCSLock Lock(m_CSTasks); + std::swap(Tasks, m_Tasks); + } + + // Execute and delete each task: + for (cTasks::iterator itr = m_Tasks.begin(), end = m_Tasks.end(); itr != end; ++itr) + { + (*itr)->Run(*this); + delete *itr; + } // for itr - m_Tasks[] +} + + + + + void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); @@ -2307,6 +2330,25 @@ void cWorld::SaveAllChunks(void) +void cWorld::QueueSaveAllChunks(void) +{ + QueueTask(new cWorld::cTaskSaveAllChunks); +} + + + + + +void cWorld::QueueTask(cTask * a_Task) +{ + cCSLock Lock(m_CSTasks); + m_Tasks.push_back(a_Task); +} + + + + + void cWorld::AddEntity(cEntity * a_Entity) { m_ChunkMap->AddEntity(a_Entity); @@ -2552,3 +2594,15 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld::cTaskSaveAllChunks: + +void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World) +{ + a_World.SaveAllChunks(); +} + + + + diff --git a/source/World.h b/source/World.h index a12a9e40e..d84920470 100644 --- a/source/World.h +++ b/source/World.h @@ -69,6 +69,24 @@ public: public: cLock(cWorld & a_World); } ; + + /// A common ancestor for all tasks queued onto the tick thread + class cTask + { + public: + virtual void Run(cWorld & a_World) = 0; + } ; + + typedef std::vector cTasks; + + class cTaskSaveAllChunks : + public cTask + { + protected: + // cTask overrides: + virtual void Run(cWorld & a_World) override; + } ; + // tolua_begin @@ -461,10 +479,17 @@ public: if(a_Z < 0 && a_Z % cChunkDef::Width != 0) a_ChunkZ--; } - void SaveAllChunks(void); // tolua_export + /// Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead + void SaveAllChunks(void); // tolua_export + + /// Queues a task to save all chunks onto the tick thread. The prefferred way of saving chunks from external sources + void QueueSaveAllChunks(void); // tolua_export + + /// Queues a task onto the tick thread. The task object will be deleted once the task is finished + void QueueTask(cTask * a_Task); /// Returns the number of chunks loaded - int GetNumChunks() const; // tolua_export + int GetNumChunks() const; // tolua_export /// Returns the number of chunks loaded and dirty, and in the lighting queue void GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLightingQueue); @@ -629,6 +654,12 @@ private: cChunkSender m_ChunkSender; cLightingThread m_Lighting; cTickThread m_TickThread; + + /// Guards the m_Tasks + cCriticalSection m_CSTasks; + + /// Tasks that have been queued onto the tick thread; guarded by m_CSTasks + cTasks m_Tasks; cWorld(const AString & a_WorldName); @@ -639,6 +670,9 @@ private: void TickWeather(float a_Dt); // Handles weather each tick void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick + /// Executes all tasks queued onto the tick thread + void TickQueuedTasks(void); + /// Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section) cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock); }; // tolua_export -- cgit v1.2.3 From 6914bf4c65425172f3535b3a81936d7f75bdd42c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 12 Aug 2013 07:55:53 +0200 Subject: Removed unused cServer::IsConnected() function. --- source/Server.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/Server.h b/source/Server.h index a00485fa2..176c82a40 100644 --- a/source/Server.h +++ b/source/Server.h @@ -46,11 +46,9 @@ public: // tolua_export int GetNumPlayers(void) const { return m_NumPlayers; } void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } - // tolua_end + void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); - // bool IsConnected(void) const { return m_bIsConnected;} // returns connection status - - void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export + // tolua_end bool Start(void); -- cgit v1.2.3 From c628ab03e9aae0b8e56f260ad02cfc7d51285a71 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 12 Aug 2013 08:35:13 +0200 Subject: Removed cServer::BroadcastChat() and cServer::SendMessage(). These two functions make it difficult to move to the new ticking system, and they aren't used anyway. If so required, they can be emulated by ForEachWorld / ForEachPlayer calls. --- source/Bindings.cpp | 78 +------------------------------------------------ source/Bindings.h | 2 +- source/ClientHandle.cpp | 14 +++++---- source/Player.cpp | 22 ++++++++++---- source/Server.cpp | 46 +++++++---------------------- source/Server.h | 11 ++++--- source/World.cpp | 2 +- 7 files changed, 42 insertions(+), 133 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 46c5f0f07..9490f733e 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:51. +** Generated automatically by tolua++-1.0.92 on 08/12/13 08:16:46. */ #ifndef __cplusplus @@ -11435,80 +11435,6 @@ static int tolua_AllToLua_cServer_SetMaxPlayers00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: BroadcastChat of class cServer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_BroadcastChat00 -static int tolua_AllToLua_cServer_BroadcastChat00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"const cClientHandle",1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); - const AString a_Message = ((const AString) tolua_tocppstring(tolua_S,2,0)); - const cClientHandle* a_Exclude = ((const cClientHandle*) tolua_tousertype(tolua_S,3,NULL)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'BroadcastChat'", NULL); -#endif - { - self->BroadcastChat(a_Message,a_Exclude); - tolua_pushcppstring(tolua_S,(const char*)a_Message); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'BroadcastChat'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SendMessage of class cServer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_SendMessage00 -static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cServer",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",1,&tolua_err) || - !tolua_isboolean(tolua_S,4,1,&tolua_err) || - !tolua_isnoobj(tolua_S,5,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); - const AString a_Message = ((const AString) tolua_tocppstring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,NULL)); - bool a_bExclude = ((bool) tolua_toboolean(tolua_S,4,false)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); -#endif - { - self->SendMessage(a_Message,a_Player,a_bExclude); - tolua_pushcppstring(tolua_S,(const char*)a_Message); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); - return 0; -#endif -} -#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) @@ -29850,8 +29776,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetMaxPlayers",tolua_AllToLua_cServer_GetMaxPlayers00); tolua_function(tolua_S,"GetNumPlayers",tolua_AllToLua_cServer_GetNumPlayers00); tolua_function(tolua_S,"SetMaxPlayers",tolua_AllToLua_cServer_SetMaxPlayers00); - 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); diff --git a/source/Bindings.h b/source/Bindings.h index 10f874e41..8bc484aa0 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/11/13 20:59:52. +** Generated automatically by tolua++-1.0.92 on 08/12/13 08:16:46. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 14b052652..54e191281 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1355,12 +1355,14 @@ void cClientHandle::Tick(float a_Dt) m_ShouldCheckDownloaded = false; } + if (m_Player == NULL) + { + return; + } + // Send a ping packet: cTimer t1; - if ( - (m_Player != NULL) && // Is logged in? - (m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime()) - ) + if ((m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime())) { m_PingID++; m_PingStartTime = t1.GetNowTime(); @@ -1369,7 +1371,7 @@ void cClientHandle::Tick(float a_Dt) } // Handle block break animation: - if ((m_Player != NULL) && (m_BlockDigAnimStage > -1)) + if (m_BlockDigAnimStage > -1) { int lastAnimVal = m_BlockDigAnimStage; m_BlockDigAnimStage += (int)(m_BlockDigAnimSpeed * a_Dt); @@ -1955,7 +1957,7 @@ void cClientHandle::SendConfirmPosition(void) if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player)) { // Broadcast that this player has joined the game! Yay~ - cRoot::Get()->GetServer()->BroadcastChat(m_Username + " joined the game!", this); + m_Player->GetWorld()->BroadcastChat(m_Username + " joined the game!", this); } SendPlayerMoveLook(); diff --git a/source/Player.cpp b/source/Player.cpp index 03c871736..df7e1d539 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -129,6 +129,12 @@ bool cPlayer::Initialize(cWorld * a_World) { if (super::Initialize(a_World)) { + // Remove the client handle from the server, it will be ticked from this object from now on + if (m_ClientHandle != NULL) + { + cRoot::Get()->GetServer()->ClientMovedToWorld(m_ClientHandle); + } + GetWorld()->AddPlayer(this); return true; } @@ -175,18 +181,22 @@ void cPlayer::SpawnOn(cClientHandle & a_Client) void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) { - if (!m_ClientHandle->IsPlaying()) + if (m_ClientHandle != NULL) { - // We're not yet in the game, ignore everything - return; + if (!m_ClientHandle->IsPlaying()) + { + // We're not yet in the game, ignore everything + return; + } + m_ClientHandle->Tick(a_Dt); } super::Tick(a_Dt, a_Chunk); - // set player swimming state - SetSwimState( a_Chunk); + // Set player swimming state + SetSwimState(a_Chunk); - // handle air drowning stuff + // Handle air drowning stuff HandleAir(); if (m_bDirtyPosition) diff --git a/source/Server.cpp b/source/Server.cpp index 0045d4808..82a4cb9f5 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -162,6 +162,16 @@ void cServer::RemoveClient(const cClientHandle * a_Client) +void cServer::ClientMovedToWorld(const cClientHandle * a_Client) +{ + cCSLock Lock(m_CSClients); + m_Clients.remove(const_cast(a_Client)); +} + + + + + bool cServer::InitServer(cIniFile & a_SettingsIni) { m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str(); @@ -298,23 +308,6 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket) -void cServer::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude) -{ - cCSLock Lock(m_CSClients); - for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) - { - if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn()) - { - continue; - } - (*itr)->SendChat(a_Message); - } -} - - - - - bool cServer::Tick(float a_Dt) { cRoot::Get()->TickCommands(); @@ -452,25 +445,6 @@ void cServer::BindBuiltInConsoleCommands(void) -void cServer::SendMessage(const AString & a_Message, cPlayer * a_Player /* = NULL */, bool a_bExclude /* = false */ ) -{ - if ((a_Player != NULL) && !a_bExclude) - { - cClientHandle * Client = a_Player->GetClientHandle(); - if (Client != NULL) - { - Client->SendChat(a_Message); - } - return; - } - - BroadcastChat(a_Message, (a_Player != NULL) ? a_Player->GetClientHandle() : NULL); -} - - - - - void cServer::Shutdown(void) { m_ListenThreadIPv4.Stop(); diff --git a/source/Server.h b/source/Server.h index 176c82a40..fad7fc12a 100644 --- a/source/Server.h +++ b/source/Server.h @@ -46,8 +46,6 @@ public: // tolua_export int GetNumPlayers(void) const { return m_NumPlayers; } void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } - void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); - // tolua_end bool Start(void); @@ -62,8 +60,6 @@ public: // tolua_export void Shutdown(void); - void SendMessage(const AString & a_Message, cPlayer * a_Player = NULL, bool a_bExclude = false ); // tolua_export - void KickUser(int a_ClientID, const AString & a_Reason); void AuthenticateUser(int a_ClientID); // Called by cAuthenticator to auth the specified user @@ -79,6 +75,9 @@ public: // tolua_export void RemoveClient(const cClientHandle * a_Client); // Removes the clienthandle from m_SocketThreads + /// Don't tick a_Client anymore, it will be ticked from its cPlayer instead + void ClientMovedToWorld(const cClientHandle * a_Client); + CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; } CryptoPP::RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; } @@ -132,8 +131,8 @@ private: cListenThread m_ListenThreadIPv4; cListenThread m_ListenThreadIPv6; - cCriticalSection m_CSClients; // Locks client list - cClientHandleList m_Clients; // Clients that are connected to the server + cCriticalSection m_CSClients; ///< Locks client list + cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld cSocketThreads m_SocketThreads; diff --git a/source/World.cpp b/source/World.cpp index 341682a2a..b29bc751f 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -578,7 +578,7 @@ void cWorld::Tick(float a_Dt) m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); - // Broadcase time update every 40 ticks (2 seconds) + // Broadcast time update every 40 ticks (2 seconds) if (m_LastTimeUpdate < m_WorldAge - 40) { BroadcastTimeUpdate(); -- cgit v1.2.3 From 27d0c9aef2d25b4d1f81f5b361f3f1f0ab9efc27 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 12 Aug 2013 08:42:18 +0200 Subject: Fixed logging into debug console. Was missing the LF at the end. --- source/Log.cpp | 2 +- source/MCLogger.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/Log.cpp b/source/Log.cpp index 2b505de5d..c8937c380 100644 --- a/source/Log.cpp +++ b/source/Log.cpp @@ -138,7 +138,7 @@ void cLog::Log(const char * a_Format, va_list argList) #if defined (_WIN32) && defined(_DEBUG) // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA(Line.c_str()); + OutputDebugStringA((Line + "\n").c_str()); #endif // _WIN32 } diff --git a/source/MCLogger.cpp b/source/MCLogger.cpp index de0fcae2e..2870d8ba1 100644 --- a/source/MCLogger.cpp +++ b/source/MCLogger.cpp @@ -75,7 +75,9 @@ cMCLogger::~cMCLogger() m_Log->Log("--- Stopped Log ---\n"); delete m_Log; if (this == s_MCLogger) + { s_MCLogger = NULL; + } } -- cgit v1.2.3 From 9020dc993241a4a90e8e98b3435d9b2576f313ea Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 13 Aug 2013 22:45:29 +0200 Subject: Clients are now ticked in cServer first, then in cWorld once they get assigned a world. --- source/Bindings.cpp | 86 +------------------------------------------------ source/Bindings.h | 2 +- source/ClientHandle.cpp | 63 ++++++++++++++++++------------------ source/ClientHandle.h | 25 ++++++++------ source/Player.cpp | 34 ++++++++++--------- source/Player.h | 2 +- source/Server.cpp | 48 +++++++++++++++++++-------- source/Server.h | 8 +++-- source/World.cpp | 66 ++++++++++++++++++++++++++++++++----- source/World.h | 16 +++++++-- 10 files changed, 182 insertions(+), 168 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 9490f733e..0424d5f41 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/12/13 08:16:46. +** Generated automatically by tolua++-1.0.92 on 08/12/13 21:48:05. */ #ifndef __cplusplus @@ -8237,40 +8237,6 @@ static int tolua_AllToLua_Lua__cEntity_cEntity__IsRclking00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: Initialize of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Initialize00 -static int tolua_AllToLua_cPlayer_Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Initialize'", NULL); -#endif - { - bool tolua_ret = (bool) self->Initialize(a_World); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: GetEyeHeight of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEyeHeight00 static int tolua_AllToLua_cPlayer_GetEyeHeight00(lua_State* tolua_S) @@ -10186,17 +10152,6 @@ static int tolua_AllToLua_cPlayer_IsSubmerged00(lua_State* tolua_S) class Lua__cPlayer : public cPlayer, public ToluaBase { public: - bool Initialize( cWorld* a_World) { - if (push_method("Initialize", tolua_AllToLua_cPlayer_Initialize00)) { - tolua_pushusertype(lua_state, (void*)a_World, "cWorld"); - ToluaBase::dbcall(lua_state, 2, 1); - bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); - lua_pop(lua_state, 1); - return tolua_ret; - } else { - return ( bool ) cPlayer:: Initialize(a_World); - }; - }; void MoveTo( const Vector3d& a_NewPos) { if (push_method("MoveTo", tolua_AllToLua_cPlayer_MoveTo00)) { tolua_pushusertype(lua_state, (void*)&a_NewPos, "const Vector3d"); @@ -10418,9 +10373,6 @@ public: }; }; - bool cPlayer__Initialize( cWorld* a_World) { - return ( bool )cPlayer::Initialize(a_World); - }; void cPlayer__MoveTo( const Vector3d& a_NewPos) { return ( void )cPlayer::MoveTo(a_NewPos); }; @@ -10522,40 +10474,6 @@ static int tolua_AllToLua_Lua__cPlayer_tolua__set_instance00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: cPlayer__Initialize of class Lua__cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00 -static int tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"Lua__cPlayer",0,&tolua_err) || - !tolua_isusertype(tolua_S,2,"cWorld",0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - Lua__cPlayer* self = (Lua__cPlayer*) tolua_tousertype(tolua_S,1,0); - cWorld* a_World = ((cWorld*) tolua_tousertype(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlayer__Initialize'", NULL); -#endif - { - bool tolua_ret = (bool) self->cPlayer__Initialize(a_World); - tolua_pushboolean(tolua_S,(bool)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'cPlayer__Initialize'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: cPlayer__MoveTo of class Lua__cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00 static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S) @@ -29625,7 +29543,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"EATING_TICKS",cPlayer::EATING_TICKS); tolua_constant(tolua_S,"MAX_AIR_LEVEL",cPlayer::MAX_AIR_LEVEL); tolua_constant(tolua_S,"DROWNING_TICKS",cPlayer::DROWNING_TICKS); - tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00); tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00); tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00); tolua_function(tolua_S,"IsOnGround",tolua_AllToLua_cPlayer_IsOnGround00); @@ -29688,7 +29605,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); tolua_beginmodule(tolua_S,"Lua__cPlayer"); tolua_function(tolua_S,"tolua__set_instance",tolua_AllToLua_Lua__cPlayer_tolua__set_instance00); - tolua_function(tolua_S,"cPlayer__Initialize",tolua_AllToLua_Lua__cPlayer_cPlayer__Initialize00); tolua_function(tolua_S,"cPlayer__MoveTo",tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00); tolua_function(tolua_S,"cPlayer__IsSwimming",tolua_AllToLua_Lua__cPlayer_cPlayer__IsSwimming00); tolua_function(tolua_S,"cPlayer__IsSubmerged",tolua_AllToLua_Lua__cPlayer_cPlayer__IsSubmerged00); diff --git a/source/Bindings.h b/source/Bindings.h index 8bc484aa0..90043e826 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/12/13 08:16:46. +** Generated automatically by tolua++-1.0.92 on 08/12/13 21:48:06. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 54e191281..fe78ef2b6 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -170,13 +170,21 @@ cClientHandle::~cClientHandle() -void cClientHandle::Destroy() +void cClientHandle::Destroy(void) { - // Setting m_bDestroyed was moved to the bottom of Destroy(), - // otherwise the destructor may be called within another thread before the client is removed from chunks - // http://forum.mc-server.org/showthread.php?tid=366 + { + cCSLock Lock(m_CSDestroyingState); + if (m_State >= csDestroying) + { + // Already called + return; + } + m_State = csDestroying; + } + + // DEBUG: + LOGD("%s: client %p, \"%s\"", __FUNCTION__, this, m_Username.c_str()); - m_State = csDestroying; if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) { RemoveFromAllChunks(); @@ -253,9 +261,8 @@ void cClientHandle::Authenticate(void) SendGameMode(m_Player->GetGameMode()); m_Player->Initialize(World); - StreamChunks(); - m_State = csDownloadingWorld; - + m_State = csAuthenticated; + // Broadcast this player's spawning to all other players in the same chunk m_Player->GetWorld()->BroadcastSpawnEntity(*m_Player, this); @@ -1342,6 +1349,20 @@ bool cClientHandle::CheckBlockInteractionsRate(void) void cClientHandle::Tick(float a_Dt) { + // Process received network data: + AString IncomingData; + { + cCSLock Lock(m_CSIncomingData); + std::swap(IncomingData, m_IncomingData); + } + m_Protocol->DataReceived(IncomingData.data(), IncomingData.size()); + + if (m_State == csAuthenticated) + { + StreamChunks(); + m_State = csDownloadingWorld; + } + m_TimeSinceLastPacket += a_Dt; if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out { @@ -2118,30 +2139,10 @@ void cClientHandle::PacketError(unsigned char a_PacketType) void cClientHandle::DataReceived(const char * a_Data, int a_Size) { - // Data is received from the client, hand it off to the protocol: - if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) - { - /* - _X: Lock the world, so that plugins reacting to protocol events have already the chunkmap locked. - There was a possibility of a deadlock between SocketThreads and TickThreads, resulting from each - holding one CS an requesting the other one (ChunkMap CS vs Plugin CS) (FS #375). To break this, it's - sufficient to break any of the four Coffman conditions for a deadlock. We'll solve this by requiring - the ChunkMap CS for all SocketThreads operations before they lock the PluginCS - thus creating a kind - of a lock hierarchy. However, this incurs a performance penalty, we're de facto locking the chunkmap - for each incoming packet. A better, but more involved solutin would be to lock the chunkmap only when - the incoming packet really has a plugin CS lock request. - Also, it is still possible for a packet to slip through - when a player still doesn't have their world - assigned and several packets arrive at once. - */ - cWorld::cLock(*m_Player->GetWorld()); - - m_Protocol->DataReceived(a_Data, a_Size); - } - else - { - m_Protocol->DataReceived(a_Data, a_Size); - } + // Data is received from the client, store it in the buffer to be processed by the Tick thread: m_TimeSinceLastPacket = 0; + cCSLock Lock(m_CSIncomingData); + m_IncomingData.append(a_Data, a_Size); } diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 73edaf73c..1f40cc8d2 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -212,11 +212,12 @@ private: cProtocol * m_Protocol; + cCriticalSection m_CSIncomingData; + AString m_IncomingData; + cCriticalSection m_CSOutgoingData; cByteBuffer m_OutgoingData; - AString m_OutgoingDataOverflow; //< For data that didn't fit into the m_OutgoingData ringbuffer temporarily - - cCriticalSection m_CriticalSection; + AString m_OutgoingDataOverflow; ///< For data that didn't fit into the m_OutgoingData ringbuffer temporarily Vector3d m_ConfirmPosition; @@ -252,18 +253,22 @@ private: enum eState { - csConnected, // The client has just connected, waiting for their handshake / login - csAuthenticating, // The client has logged in, waiting for external authentication - csDownloadingWorld, // The client is waiting for chunks, we're waiting for the loader to provide and send them - csConfirmingPos, // The client has been sent the position packet, waiting for them to repeat the position back - csPlaying, // Normal gameplay - csDestroying, // The client is being destroyed, don't queue any more packets / don't add to chunks - csDestroyed, // The client has been destroyed, the destructor is to be called from the owner thread + csConnected, ///< The client has just connected, waiting for their handshake / login + csAuthenticating, ///< The client has logged in, waiting for external authentication + csAuthenticated, ///< The client has been authenticated, will start streaming chunks in the next tick + csDownloadingWorld, ///< The client is waiting for chunks, we're waiting for the loader to provide and send them + csConfirmingPos, ///< The client has been sent the position packet, waiting for them to repeat the position back + csPlaying, ///< Normal gameplay + csDestroying, ///< The client is being destroyed, don't queue any more packets / don't add to chunks + csDestroyed, ///< The client has been destroyed, the destructor is to be called from the owner thread // TODO: Add Kicking here as well } ; eState m_State; + + /// m_State needs to be locked in the Destroy() function so that the destruction code doesn't run twice on two different threads + cCriticalSection m_CSDestroyingState; bool m_bKeepThreadGoing; diff --git a/source/Player.cpp b/source/Player.cpp index df7e1d539..9ca619cf7 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -127,6 +127,8 @@ cPlayer::~cPlayer(void) bool cPlayer::Initialize(cWorld * a_World) { + ASSERT(a_World != NULL); + if (super::Initialize(a_World)) { // Remove the client handle from the server, it will be ticked from this object from now on @@ -148,6 +150,7 @@ bool cPlayer::Initialize(cWorld * a_World) void cPlayer::Destroyed() { CloseWindow(false); + m_ClientHandle = NULL; } @@ -157,22 +160,17 @@ void cPlayer::Destroyed() void cPlayer::SpawnOn(cClientHandle & a_Client) { - /* - LOGD("cPlayer::SpawnOn(%s) for \"%s\" at pos {%.2f, %.2f, %.2f}", - a_Client.GetUsername().c_str(), m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z - ); - */ - - if (m_bVisible && (m_ClientHandle != (&a_Client))) + if (!m_bVisible || (m_ClientHandle == (&a_Client))) { - a_Client.SendPlayerSpawn(*this); - a_Client.SendEntityHeadLook(*this); - a_Client.SendEntityEquipment(*this, 0, m_Inventory.GetEquippedItem() ); - a_Client.SendEntityEquipment(*this, 1, m_Inventory.GetEquippedBoots() ); - a_Client.SendEntityEquipment(*this, 2, m_Inventory.GetEquippedLeggings() ); - a_Client.SendEntityEquipment(*this, 3, m_Inventory.GetEquippedChestplate() ); - a_Client.SendEntityEquipment(*this, 4, m_Inventory.GetEquippedHelmet() ); + return; } + a_Client.SendPlayerSpawn(*this); + a_Client.SendEntityHeadLook(*this); + a_Client.SendEntityEquipment(*this, 0, m_Inventory.GetEquippedItem() ); + a_Client.SendEntityEquipment(*this, 1, m_Inventory.GetEquippedBoots() ); + a_Client.SendEntityEquipment(*this, 2, m_Inventory.GetEquippedLeggings() ); + a_Client.SendEntityEquipment(*this, 3, m_Inventory.GetEquippedChestplate() ); + a_Client.SendEntityEquipment(*this, 4, m_Inventory.GetEquippedHelmet() ); } @@ -183,12 +181,18 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) { if (m_ClientHandle != NULL) { + if (m_ClientHandle->IsDestroyed()) + { + // This should not happen, because destroying a client will remove it from the world, but just in case + m_ClientHandle = NULL; + return; + } + if (!m_ClientHandle->IsPlaying()) { // We're not yet in the game, ignore everything return; } - m_ClientHandle->Tick(a_Dt); } super::Tick(a_Dt, a_Chunk); diff --git a/source/Player.h b/source/Player.h index 105e7d0a1..2a1797c79 100644 --- a/source/Player.h +++ b/source/Player.h @@ -40,7 +40,7 @@ public: cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); virtual ~cPlayer(); - virtual bool Initialize(cWorld * a_World); // tolua_export + virtual bool Initialize(cWorld * a_World) override; virtual void SpawnOn(cClientHandle & a_Client) override; diff --git a/source/Server.cpp b/source/Server.cpp index 82a4cb9f5..31a1925a8 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -165,7 +165,7 @@ void cServer::RemoveClient(const cClientHandle * a_Client) void cServer::ClientMovedToWorld(const cClientHandle * a_Client) { cCSLock Lock(m_CSClients); - m_Clients.remove(const_cast(a_Client)); + m_ClientsToRemove.push_back(const_cast(a_Client)); } @@ -312,14 +312,44 @@ bool cServer::Tick(float a_Dt) { cRoot::Get()->TickCommands(); + TickClients(a_Dt); + + if (!m_bRestarting) + { + return true; + } + else + { + m_bRestarting = false; + m_RestartEvent.Set(); + return false; + } +} + + + + + +void cServer::TickClients(float a_Dt) +{ cClientHandleList RemoveClients; { cCSLock Lock(m_CSClients); + + // Remove clients that have moved to a world (the world will be ticking them from now on) + for (cClientHandleList::const_iterator itr = m_ClientsToRemove.begin(), end = m_ClientsToRemove.end(); itr != end; ++itr) + { + m_Clients.remove(*itr); + } // for itr - m_ClientsToRemove[] + m_ClientsToRemove.clear(); + + // Tick the remaining clients, take out those that have been destroyed into RemoveClients for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) { if ((*itr)->IsDestroyed()) { - RemoveClients.push_back(*itr); // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 ) + // Remove the client later, when CS is not held, to avoid deadlock ( http://forum.mc-server.org/showthread.php?tid=374 ) + RemoveClients.push_back(*itr); itr = m_Clients.erase(itr); continue; } @@ -327,21 +357,12 @@ bool cServer::Tick(float a_Dt) ++itr; } // for itr - m_Clients[] } + + // Delete the clients that have been destroyed for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) { delete *itr; } // for itr - RemoveClients[] - - if (!m_bRestarting) - { - return true; - } - else - { - m_bRestarting = false; - m_RestartEvent.Set(); - return false; - } } @@ -492,6 +513,7 @@ void cServer::AuthenticateUser(int a_ClientID) if ((*itr)->GetUniqueID() == a_ClientID) { (*itr)->Authenticate(); + return; } } // for itr - m_Clients[] } diff --git a/source/Server.h b/source/Server.h index fad7fc12a..6f8576ece 100644 --- a/source/Server.h +++ b/source/Server.h @@ -131,8 +131,9 @@ private: cListenThread m_ListenThreadIPv4; cListenThread m_ListenThreadIPv6; - cCriticalSection m_CSClients; ///< Locks client list - cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld + cCriticalSection m_CSClients; ///< Locks client lists + cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld + cClientHandleList m_ClientsToRemove; ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick() cSocketThreads m_SocketThreads; @@ -164,6 +165,9 @@ private: void PrepareKeys(void); bool Tick(float a_Dt); + + /// Ticks the clients in m_Clients, manages the list in respect to removing clients + void TickClients(float a_Dt); // cListenThread::cCallback overrides: virtual void OnConnectionAccepted(cSocket & a_Socket) override; diff --git a/source/World.cpp b/source/World.cpp index b29bc751f..7a1ecb82e 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -587,6 +587,7 @@ void cWorld::Tick(float a_Dt) m_ChunkMap->Tick(a_Dt); + TickClients(a_Dt); TickQueuedBlocks(a_Dt); TickQueuedTasks(); @@ -811,6 +812,37 @@ void cWorld::TickQueuedTasks(void) +void cWorld::TickClients(float a_Dt) +{ + cClientHandleList RemoveClients; + { + cCSLock Lock(m_CSClients); + // Tick the clients, take out those that have been destroyed into RemoveClients + for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) + { + if ((*itr)->IsDestroyed()) + { + // Remove the client later, when CS is not held, to avoid deadlock + RemoveClients.push_back(*itr); + itr = m_Clients.erase(itr); + continue; + } + (*itr)->Tick(a_Dt); + ++itr; + } // for itr - m_Clients[] + } + + // Delete the clients that have been destroyed + for (cClientHandleList::iterator itr = RemoveClients.begin(); itr != RemoveClients.end(); ++itr) + { + delete *itr; + } // for itr - RemoveClients[] +} + + + + + void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); @@ -1973,13 +2005,22 @@ void cWorld::CollectPickupsByPlayer(cPlayer * a_Player) void cWorld::AddPlayer(cPlayer * a_Player) { - cCSLock Lock(m_CSPlayers); - - ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? - - m_Players.remove(a_Player); // Make sure the player is registered only once - m_Players.push_back(a_Player); + { + cCSLock Lock(m_CSPlayers); + + ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW? + + m_Players.remove(a_Player); // Make sure the player is registered only once + m_Players.push_back(a_Player); + } + // Add the player's client to the list of clients to be ticked: + if (a_Player->GetClientHandle() != NULL) + { + cCSLock Lock(m_CSClients); + m_Clients.push_back(a_Player->GetClientHandle()); + } + // The player has already been added to the chunkmap as the entity, do NOT add again! } @@ -1990,8 +2031,17 @@ void cWorld::AddPlayer(cPlayer * a_Player) void cWorld::RemovePlayer(cPlayer * a_Player) { m_ChunkMap->RemoveEntity(a_Player); - cCSLock Lock(m_CSPlayers); - m_Players.remove(a_Player); + { + cCSLock Lock(m_CSPlayers); + m_Players.remove(a_Player); + } + + // Remove the player's client from the list of clients to be ticked: + if (a_Player->GetClientHandle() != NULL) + { + cCSLock Lock(m_CSClients); + m_Clients.remove(a_Player->GetClientHandle()); + } } diff --git a/source/World.h b/source/World.h index d84920470..da59b12f6 100644 --- a/source/World.h +++ b/source/World.h @@ -660,6 +660,12 @@ private: /// Tasks that have been queued onto the tick thread; guarded by m_CSTasks cTasks m_Tasks; + + /// Guards m_Clients + cCriticalSection m_CSClients; + + /// List of clients in this world, these will be ticked by this world + cClientHandleList m_Clients; cWorld(const AString & a_WorldName); @@ -667,12 +673,18 @@ private: void Tick(float a_Dt); - void TickWeather(float a_Dt); // Handles weather each tick - void TickSpawnMobs(float a_Dt); // Handles mob spawning each tick + /// Handles the weather in each tick + void TickWeather(float a_Dt); + + /// Handles the mob spawning each tick + void TickSpawnMobs(float a_Dt); /// Executes all tasks queued onto the tick thread void TickQueuedTasks(void); + /// Ticks all clients that are in this world + void TickClients(float a_Dt); + /// Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section) cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock); }; // tolua_export -- cgit v1.2.3 From 7b190f5044d019e6f6c849aac325517d54372b51 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 13 Aug 2013 23:06:23 +0200 Subject: Updated the Core Lua files in MCServer project externals. --- VC2008/MCServer.vcproj | 68 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index b39cf2769..4d850626d 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -2449,7 +2449,15 @@ Name="Core" > + + + + + + + + + + + + + + @@ -2580,6 +2608,10 @@ RelativePath="..\MCServer\Plugins\Core\web_whitelist.lua" > + + Date: Tue, 13 Aug 2013 23:10:59 +0200 Subject: Exported cWorld:BroadcastChat() to the Lua API; used in the Core. --- MCServer/Plugins/Core/onjoinleave.lua | 37 ++++++++++++++++----------------- source/Bindings.cpp | 39 ++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/World.h | 4 ++-- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/MCServer/Plugins/Core/onjoinleave.lua b/MCServer/Plugins/Core/onjoinleave.lua index c794aaf94..cd0ead4fc 100644 --- a/MCServer/Plugins/Core/onjoinleave.lua +++ b/MCServer/Plugins/Core/onjoinleave.lua @@ -1,24 +1,23 @@ + + + + + function OnPlayerJoined(Player) - --if( BannedPlayersIni:GetValueB("Banned", Player:GetName(), false) == true ) then - -- LOGINFO( Player:GetName() .. " tried to join, but is banned!" ) - -- KickPlayer(Player:GetName(), cChatColor.Red .. "You are banned!" ) - -- return true - --elseif( WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false ) == true ) then - -- if( WhiteListIni:GetValueB("WhiteList", Player:GetName(), false ) == false ) then - -- LOGINFO( Player:GetName() .. " tried to join, but is not whitelisted!" ) - -- KickPlayer(Player:GetName(), cChatColor.Red .. "You are not whitelisted!" ) - -- end - --else - ShowMOTDTo( Player ) - local Server = cRoot:Get():GetServer() - Server:SendMessage(cChatColor.Yellow .. "[JOIN] " .. cChatColor.White .. Player:GetName() .. " has joined the game" ) - return false - --end + ShowMOTDTo(Player) + Player:GetWorld():BroadcastChat(cChatColor.Yellow .. "[JOIN] " .. cChatColor.White .. Player:GetName() .. " has joined the game") + return false end + + + + function OnDisconnect(Player, Reason) - local Server = cRoot:Get():GetServer() - Server:SendMessage(cChatColor.Yellow .. "[LEAVE] " .. cChatColor.White .. Player:GetName() .. " has left the game" ) - LOG("Player " .. Player:GetName() .. " has left the game.") + Player:GetWorld():BroadcastChat(cChatColor.Yellow .. "[LEAVE] " .. cChatColor.White .. Player:GetName() .. " has left the game") return true -end \ No newline at end of file +end + + + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index e7a71ce76..8feb070e1 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/13/13 23:00:22. +** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:52. */ #ifndef __cplusplus @@ -11896,6 +11896,42 @@ static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: BroadcastChat of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_BroadcastChat00 +static int tolua_AllToLua_cWorld_BroadcastChat00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isusertype(tolua_S,3,"const cClientHandle",1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + const AString a_Message = ((const AString) tolua_tocppstring(tolua_S,2,0)); + const cClientHandle* a_Exclude = ((const cClientHandle*) tolua_tousertype(tolua_S,3,NULL)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'BroadcastChat'", NULL); +#endif + { + self->BroadcastChat(a_Message,a_Exclude); + tolua_pushcppstring(tolua_S,(const char*)a_Message); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'BroadcastChat'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: UnloadUnusedChunks of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_UnloadUnusedChunks00 static int tolua_AllToLua_cWorld_UnloadUnusedChunks00(lua_State* tolua_S) @@ -29713,6 +29749,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsDeepSnowEnabled",tolua_AllToLua_cWorld_IsDeepSnowEnabled00); tolua_function(tolua_S,"GetDimension",tolua_AllToLua_cWorld_GetDimension00); tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cWorld_GetHeight00); + tolua_function(tolua_S,"BroadcastChat",tolua_AllToLua_cWorld_BroadcastChat00); tolua_function(tolua_S,"UnloadUnusedChunks",tolua_AllToLua_cWorld_UnloadUnusedChunks00); tolua_function(tolua_S,"RegenerateChunk",tolua_AllToLua_cWorld_RegenerateChunk00); tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00); diff --git a/source/Bindings.h b/source/Bindings.h index 1e5ad7e84..a8d39e32f 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/13/13 23:00:22. +** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:53. */ /* Exported function */ diff --git a/source/World.h b/source/World.h index da59b12f6..2c04c4cc6 100644 --- a/source/World.h +++ b/source/World.h @@ -154,8 +154,8 @@ public: void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle); void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); - void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude - void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL); + void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude + void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); -- cgit v1.2.3 From 8c3837987bd5f74563790c15a1d52755383135ae Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 10:24:34 +0200 Subject: Player counts are now properly handled. Fixes #80 --- source/Bindings.cpp | 6 +++--- source/Bindings.h | 2 +- source/ClientHandle.cpp | 38 +++++++++++++++++++++++++++++++++++++- source/ClientHandle.h | 4 ++++ source/Player.cpp | 15 ++++++--------- source/Server.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ source/Server.h | 14 ++++++++++++-- 7 files changed, 108 insertions(+), 16 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 8feb070e1..a0ad85156 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:52. +** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:03. */ #ifndef __cplusplus @@ -11295,14 +11295,14 @@ static int tolua_AllToLua_cServer_GetNumPlayers00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"const cServer",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"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); + cServer* self = (cServer*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNumPlayers'", NULL); #endif diff --git a/source/Bindings.h b/source/Bindings.h index a8d39e32f..0211e0eeb 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/13/13 23:07:53. +** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:04. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index fe78ef2b6..32bfb00f5 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -275,7 +275,7 @@ void cClientHandle::Authenticate(void) void cClientHandle::StreamChunks(void) { - if ((m_State < csAuthenticating) || (m_State >= csDestroying)) + if ((m_State < csAuthenticated) || (m_State >= csDestroying)) { return; } @@ -1314,6 +1314,42 @@ void cClientHandle::SendData(const char * a_Data, int a_Size) +void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket) +{ + ASSERT(m_Player != NULL); + + if (a_SendRespawnPacket) + { + SendRespawn(); + } + + cWorld * World = m_Player->GetWorld(); + + // Remove all associated chunks: + cChunkCoordsList Chunks; + { + cCSLock Lock(m_CSChunkLists); + std::swap(Chunks, m_LoadedChunks); + m_ChunksToSend.clear(); + } + for (cChunkCoordsList::iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr) + { + World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this); + m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ); + } // for itr - Chunks[] + + // Do NOT stream new chunks, the new world runs its own tick thread and may deadlock + // Instead, the chunks will be streamed when the client is moved to the new world's Tick list, + // by setting state to csAuthenticated + m_State = csAuthenticated; + m_LastStreamedChunkX = 0x7fffffff; + m_LastStreamedChunkZ = 0x7fffffff; +} + + + + + bool cClientHandle::CheckBlockInteractionsRate(void) { ASSERT(m_Player != NULL); diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 1f40cc8d2..4dcb188b3 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -32,6 +32,7 @@ class cRedstone; class cWindow; class cFallingBlock; class cItemHandler; +class cWorld; @@ -194,6 +195,9 @@ public: void SendData(const char * a_Data, int a_Size); + /// Called when the player moves into a different world; queues sreaming the new chunks + void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); + private: int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) diff --git a/source/Player.cpp b/source/Player.cpp index 365a0396f..34980d2f6 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -100,6 +100,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) m_LastJumpHeight = (float)(GetPosY()); m_LastGroundHeight = (float)(GetPosY()); m_Stance = GetPosY() + 1.62; + + cRoot::Get()->GetServer()->PlayerCreated(this); } @@ -1120,20 +1122,15 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) m_ClientHandle->RemoveFromAllChunks(); m_World->RemoveEntity(this); + // If the dimension is different, we can send the respawn packet + // http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02 + m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension())); + // Add player to all the necessary parts of the new world SetWorld(World); World->AddEntity(this); World->AddPlayer(this); - // If the dimension is different, we can send the respawn packet - // http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02 - if (OldDimension != World->GetDimension()) - { - m_ClientHandle->SendRespawn(); - } - - // Stream the new chunks: - m_ClientHandle->StreamChunks(); return true; } diff --git a/source/Server.cpp b/source/Server.cpp index 31a1925a8..c01222e5a 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -172,10 +172,34 @@ void cServer::ClientMovedToWorld(const cClientHandle * a_Client) +void cServer::PlayerCreated(const cPlayer * a_Player) +{ + // To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread + cCSLock Lock(m_CSPlayerCountDiff); + m_PlayerCountDiff += 1; +} + + + + + +void cServer::PlayerDestroyed(const cPlayer * a_Player) +{ + // To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread + cCSLock Lock(m_CSPlayerCountDiff); + m_PlayerCountDiff -= 1; +} + + + + + bool cServer::InitServer(cIniFile & a_SettingsIni) { m_Description = a_SettingsIni.GetValue ("Server", "Description", "MCServer! - In C++!").c_str(); m_MaxPlayers = a_SettingsIni.GetValueI("Server", "MaxPlayers", 100); + m_PlayerCount = 0; + m_PlayerCountDiff = 0; if (m_bIsConnected) { @@ -254,6 +278,16 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) +int cServer::GetNumPlayers(void) +{ + cCSLock Lock(m_CSPlayerCount); + return m_PlayerCount; +} + + + + + void cServer::PrepareKeys(void) { // TODO: Save and load key for persistence across sessions @@ -310,6 +344,17 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket) bool cServer::Tick(float a_Dt) { + // Apply the queued playercount adjustments (postponed to avoid deadlocks) + int PlayerCountDiff = 0; + { + cCSLock Lock(m_CSPlayerCountDiff); + std::swap(PlayerCountDiff, m_PlayerCountDiff); + } + { + cCSLock Lock(m_CSPlayerCount); + m_PlayerCount += PlayerCountDiff; + } + cRoot::Get()->TickCommands(); TickClients(a_Dt); diff --git a/source/Server.h b/source/Server.h index 6f8576ece..87e472465 100644 --- a/source/Server.h +++ b/source/Server.h @@ -43,7 +43,7 @@ public: // tolua_export // Player counts: int GetMaxPlayers(void) const {return m_MaxPlayers; } - int GetNumPlayers(void) const { return m_NumPlayers; } + int GetNumPlayers(void); void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } // tolua_end @@ -78,6 +78,12 @@ public: // tolua_export /// Don't tick a_Client anymore, it will be ticked from its cPlayer instead void ClientMovedToWorld(const cClientHandle * a_Client); + /// Notifies the server that a player was created; the server uses this to adjust the number of players + void PlayerCreated(const cPlayer * a_Player); + + /// Notifies the server that a player was destroyed; the server uses this to adjust the number of players + void PlayerDestroyed(const cPlayer * a_Player); + CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; } CryptoPP::RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; } @@ -135,6 +141,11 @@ private: cClientHandleList m_Clients; ///< Clients that are connected to the server and not yet assigned to a cWorld cClientHandleList m_ClientsToRemove; ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick() + cCriticalSection m_CSPlayerCount; ///< Locks the m_PlayerCount + int m_PlayerCount; ///< Number of players currently playing in the server + cCriticalSection m_CSPlayerCountDiff; ///< Locks the m_PlayerCountDiff + int m_PlayerCountDiff; ///< Adjustment to m_PlayerCount to be applied in the Tick thread + cSocketThreads m_SocketThreads; int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini @@ -150,7 +161,6 @@ private: AString m_Description; int m_MaxPlayers; - int m_NumPlayers; cTickThread m_TickThread; cEvent m_RestartEvent; -- cgit v1.2.3 From 1b097d2cb414ae4c3c58b923c7742cbd2734baad Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 14 Aug 2013 13:09:13 +0200 Subject: Added mtilden to contributors list. --- CONTRIBUTORS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 23d5045fa..8ac48e880 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -9,6 +9,7 @@ tigerw bearbin Lapayo rs2k -Duralex +Duralex +mtilden If you feel you have contributed enough to be included in this list, just put in a PR including yourself. -- cgit v1.2.3 From f8757d3606a9cf14a353e5b7a61b8e660a4cce6d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 13:43:55 +0200 Subject: Fixed crashes in world's clientlist manipulators --- source/World.cpp | 24 ++++++++++++++++++++++-- source/World.h | 6 ++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/source/World.cpp b/source/World.cpp index 7a1ecb82e..59240c7da 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -817,6 +817,26 @@ void cWorld::TickClients(float a_Dt) cClientHandleList RemoveClients; { cCSLock Lock(m_CSClients); + + // Remove clients scheduled for removal: + for (cClientHandleList::iterator itr = m_ClientsToRemove.begin(), end = m_ClientsToRemove.end(); itr != end; ++itr) + { + m_Clients.remove(*itr); + } // for itr - m_ClientsToRemove[] + m_ClientsToRemove.clear(); + + // Add clients scheduled for adding: + for (cClientHandleList::iterator itr = m_ClientsToAdd.begin(), end = m_ClientsToAdd.end(); itr != end; ++itr) + { + if (std::find(m_Clients.begin(), m_Clients.end(), *itr) != m_Clients.end()) + { + ASSERT(!"Adding a client that is already in the clientlist"); + continue; + } + m_Clients.push_back(*itr); + } // for itr - m_ClientsToRemove[] + m_ClientsToAdd.clear(); + // Tick the clients, take out those that have been destroyed into RemoveClients for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end();) { @@ -2018,7 +2038,7 @@ void cWorld::AddPlayer(cPlayer * a_Player) if (a_Player->GetClientHandle() != NULL) { cCSLock Lock(m_CSClients); - m_Clients.push_back(a_Player->GetClientHandle()); + m_ClientsToAdd.push_back(a_Player->GetClientHandle()); } // The player has already been added to the chunkmap as the entity, do NOT add again! @@ -2040,7 +2060,7 @@ void cWorld::RemovePlayer(cPlayer * a_Player) if (a_Player->GetClientHandle() != NULL) { cCSLock Lock(m_CSClients); - m_Clients.remove(a_Player->GetClientHandle()); + m_ClientsToRemove.push_back(a_Player->GetClientHandle()); } } diff --git a/source/World.h b/source/World.h index 2c04c4cc6..4f1e942e4 100644 --- a/source/World.h +++ b/source/World.h @@ -666,6 +666,12 @@ private: /// List of clients in this world, these will be ticked by this world cClientHandleList m_Clients; + + /// Clients that are scheduled for removal (ticked in another world), waiting for TickClients() to remove them + cClientHandleList m_ClientsToRemove; + + /// Clients that are scheduled for adding, waiting for TickClients to add them + cClientHandleList m_ClientsToAdd; cWorld(const AString & a_WorldName); -- cgit v1.2.3 From 17b2353d71c405bc626de22e5467d13be792c317 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 19:11:54 +0200 Subject: Server counts the players correctly. Was missing the PlayerDestroying() call, so players weren't removed from the playercount. --- source/Player.cpp | 3 +++ source/Server.cpp | 2 +- source/Server.h | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/Player.cpp b/source/Player.cpp index 34980d2f6..a1ea631aa 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -112,6 +112,9 @@ cPlayer::~cPlayer(void) { LOGD("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); + // Notify the server that the player is being destroyed + cRoot::Get()->GetServer()->PlayerDestroying(this); + SaveToDisk(); m_World->RemovePlayer( this ); diff --git a/source/Server.cpp b/source/Server.cpp index c01222e5a..fad562973 100644 --- a/source/Server.cpp +++ b/source/Server.cpp @@ -183,7 +183,7 @@ void cServer::PlayerCreated(const cPlayer * a_Player) -void cServer::PlayerDestroyed(const cPlayer * a_Player) +void cServer::PlayerDestroying(const cPlayer * a_Player) { // To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread cCSLock Lock(m_CSPlayerCountDiff); diff --git a/source/Server.h b/source/Server.h index 87e472465..b4fe81d8f 100644 --- a/source/Server.h +++ b/source/Server.h @@ -81,8 +81,8 @@ public: // tolua_export /// Notifies the server that a player was created; the server uses this to adjust the number of players void PlayerCreated(const cPlayer * a_Player); - /// Notifies the server that a player was destroyed; the server uses this to adjust the number of players - void PlayerDestroyed(const cPlayer * a_Player); + /// Notifies the server that a player is being destroyed; the server uses this to adjust the number of players + void PlayerDestroying(const cPlayer * a_Player); CryptoPP::RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; } CryptoPP::RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; } -- cgit v1.2.3 From a1ec14f7f8b45f8e0a69663b2d25e3b9ce7564bd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 14 Aug 2013 19:42:18 +0200 Subject: Updated CONTRIBUTING.md with basic recommendations --- CONTRIBUTING.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe7ad5313..d359f9004 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,29 @@ Code Stuff ---------- - * No magic numbers, use named constants like E_ITEM... - * Please use tabs for indentation and spaces for alignment. + * No magic numbers, use named constants: + - E_ITEM_XXX, E_BLOCK_XXX and E_META_XXX for items and blocks + - E_ENTITY_TYPE_XXX for mob types + - dimNether, dimOverworld and dimEnd for world dimension + - gmSurvival, gmCreative, gmAdventure for game modes + - wSunny, wRain, wThunderstorm for weather + - cChunkDef::Width, cChunkDef::Height for chunk dimensions (C++) + - etc. + * Instead of checking for specific value, use Is functions, if available: + - cPlayer:IsGameModeCreative() instead of (cPlayer:GetGameMode() == gmCreative) + * Please use tabs for indentation and spaces for alignment. This means that if it's at line start, it's a tab; if it's in the middle of a line, it's a space + * Alpha-sort stuff that makes sense alpha-sorting - long lists of similar items etc. + * Keep individual functions spaced out by 5 empty lines, this enhances readability and makes navigation in the source file easier. + * Add those extra parentheses to conditions, especially in C++ + - "if ((a == 1) && ((b == 2) || (c == 3)))" instead of ambiguous "if (a == 1 && b == 2 || c == 3)" + - This helps prevent mistakes such as "if (a & 1 == 0)" + * White space is free, so use it freely + - "freely" as in "plentifully", not "arbitrarily" + Copyright --------- -Your work should be licensed under the apache license, and you should add yourself to the CONTRIBUTORS file. +Your work should be licensed under the Apache license, and you should add yourself to the CONTRIBUTORS file. -If your work is not licensed under the apache license, then it must be compatible and marked as such. +If your work is not licensed under the Apache license, then it must be compatible and marked as such. Note that only plugins may choose a different license; MC-server's internals need to be single-license. -- cgit v1.2.3 From cce9642c7b3a28f6457b264c11db92f54cf143ff Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 19:49:53 +0200 Subject: Fixed wrong names for some metas. They were E_BLOCK_ instead of E_META_. --- source/Bindings.cpp | 18 +++++++++--------- source/Bindings.h | 2 +- source/BlockID.h | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index a0ad85156..1ebd858e3 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:03. +** Generated automatically by tolua++-1.0.92 on 08/14/13 19:48:00. */ #ifndef __cplusplus @@ -29138,14 +29138,14 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_META_TORCH_XP",E_META_TORCH_XP); tolua_constant(tolua_S,"E_META_TORCH_ZM",E_META_TORCH_ZM); tolua_constant(tolua_S,"E_META_TORCH_ZP",E_META_TORCH_ZP); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH); - tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE); + tolua_constant(tolua_S,"E_META_WOODEN_DOUBLE_STEP_APPLE",E_META_WOODEN_DOUBLE_STEP_APPLE); + tolua_constant(tolua_S,"E_META_WOODEN_DOUBLE_STEP_CONIFER",E_META_WOODEN_DOUBLE_STEP_CONIFER); + tolua_constant(tolua_S,"E_META_WOODEN_DOUBLE_STEP_BIRCH",E_META_WOODEN_DOUBLE_STEP_BIRCH); + tolua_constant(tolua_S,"E_META_WOODEN_DOUBLE_STEP_JUNGLE",E_META_WOODEN_DOUBLE_STEP_JUNGLE); + tolua_constant(tolua_S,"E_META_WOODEN_STEP_APPLE",E_META_WOODEN_STEP_APPLE); + tolua_constant(tolua_S,"E_META_WOODEN_STEP_CONIFER",E_META_WOODEN_STEP_CONIFER); + tolua_constant(tolua_S,"E_META_WOODEN_STEP_BIRCH",E_META_WOODEN_STEP_BIRCH); + tolua_constant(tolua_S,"E_META_WOODEN_STEP_JUNGLE",E_META_WOODEN_STEP_JUNGLE); tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE); tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE); tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA); diff --git a/source/Bindings.h b/source/Bindings.h index 0211e0eeb..583017a88 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/14/13 08:14:04. +** Generated automatically by tolua++-1.0.92 on 08/14/13 19:48:00. */ /* Exported function */ diff --git a/source/BlockID.h b/source/BlockID.h index 571087ab7..58919e1aa 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -478,16 +478,16 @@ enum E_META_TORCH_ZP = 4, // Torch attached to the ZP side of its block // E_BLOCK_WOODEN_DOUBLE_STEP metas: - E_BLOCK_WOODEN_DOUBLE_STEP_APPLE = 0, - E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER = 1, - E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH = 2, - E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE = 3, + E_META_WOODEN_DOUBLE_STEP_APPLE = 0, + E_META_WOODEN_DOUBLE_STEP_CONIFER = 1, + E_META_WOODEN_DOUBLE_STEP_BIRCH = 2, + E_META_WOODEN_DOUBLE_STEP_JUNGLE = 3, // E_BLOCK_WOODEN_STEP metas: - E_BLOCK_WOODEN_STEP_APPLE = 0, - E_BLOCK_WOODEN_STEP_CONIFER = 1, - E_BLOCK_WOODEN_STEP_BIRCH = 2, - E_BLOCK_WOODEN_STEP_JUNGLE = 3, + E_META_WOODEN_STEP_APPLE = 0, + E_META_WOODEN_STEP_CONIFER = 1, + E_META_WOODEN_STEP_BIRCH = 2, + E_META_WOODEN_STEP_JUNGLE = 3, // E_BLOCK_WOOL metas: E_META_WOOL_WHITE = 0, -- cgit v1.2.3 From e2ff4a2e5c654e1c4c33f5a9098bef35e0755897 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 19:56:29 +0200 Subject: Clients are deleted when the world is stopped. This fixes #92. --- source/World.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/World.cpp b/source/World.cpp index 59240c7da..5c3a24177 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -552,6 +552,17 @@ void cWorld::Start(void) void cWorld::Stop(void) { + // Delete the clients that have been in this world: + { + cCSLock Lock(m_CSClients); + for (cClientHandleList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) + { + (*itr)->Destroy(); + delete *itr; + } // for itr - m_Clients[] + m_Clients.clear(); + } + m_TickThread.Stop(); m_Lighting.Stop(); m_Generator.Stop(); -- cgit v1.2.3 From 0af2a0b08c1570199631530db066e442701e7357 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 20:08:05 +0200 Subject: ClientHandle no longer queues chat messages. It is no longer needed to queue chat messages, because the protocol is parsed within the Tick thread itself, without holding any SocketThread CS. --- source/ClientHandle.cpp | 64 +++++++++++++------------------------------------ source/ClientHandle.h | 9 ------- 2 files changed, 17 insertions(+), 56 deletions(-) diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 32bfb00f5..dce2bbd25 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -921,11 +921,24 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c void cClientHandle::HandleChat(const AString & a_Message) { - // We need to process messages in the Tick thread, to avoid deadlocks resulting from player-commands being processed - // in the SocketThread and waiting for acquiring the ChunkMap CS with Plugin CS locked + // We no longer need to postpone message processing, because the messages already arrive in the Tick thread - cCSLock Lock(m_CSMessages); - m_PendingMessages.push_back(a_Message); + // If a command, perform it: + AString Message(a_Message); + if (cRoot::Get()->GetServer()->Command(*this, Message)) + { + return; + } + + // Not a command, broadcast as a simple message: + AString Msg; + Printf(Msg, "<%s%s%s> %s", + m_Player->GetColor().c_str(), + m_Player->GetName().c_str(), + cChatColor::White.c_str(), + Message.c_str() + ); + m_Player->GetWorld()->BroadcastChat(Msg); } @@ -1446,9 +1459,6 @@ void cClientHandle::Tick(float a_Dt) m_CurrentExplosionTick = (m_CurrentExplosionTick + 1) % ARRAYCOUNT(m_NumExplosionsPerTick); m_RunningSumExplosions -= m_NumExplosionsPerTick[m_CurrentExplosionTick]; m_NumExplosionsPerTick[m_CurrentExplosionTick] = 0; - - // Process the queued messages: - ProcessPendingMessages(); } @@ -2096,46 +2106,6 @@ void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) -void cClientHandle::ProcessPendingMessages(void) -{ - while (true) - { - AString Message; - - // Extract one message from the PendingMessages buffer: - { - cCSLock Lock(m_CSMessages); - if (m_PendingMessages.empty()) - { - // No more messages in the buffer, bail out - return; - } - Message = m_PendingMessages.front(); - m_PendingMessages.pop_front(); - } // Lock(m_CSMessages) - - // If a command, perform it: - if (cRoot::Get()->GetServer()->Command(*this, Message)) - { - continue; - } - - // Not a command, broadcast as a simple message: - AString Msg; - Printf(Msg, "<%s%s%s> %s", - m_Player->GetColor().c_str(), - m_Player->GetName().c_str(), - cChatColor::White.c_str(), - Message.c_str() - ); - m_Player->GetWorld()->BroadcastChat(Msg); - } // while (true) -} - - - - - void cClientHandle::PacketBufferFull(void) { // Too much data in the incoming queue, the server is probably too busy, kick the client: diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 4dcb188b3..9454b9b7a 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -288,12 +288,6 @@ private: /// Running sum of m_NumExplosionsPerTick[] int m_RunningSumExplosions; - /// Lock for the m_PendingMessages buffer - cCriticalSection m_CSMessages; - - /// Buffer for received messages to be processed in the Tick thread - AStringList m_PendingMessages; - static int s_ClientCount; int m_UniqueID; @@ -320,9 +314,6 @@ private: /// Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler); - /// Processes the messages in m_PendingMessages; called from the Tick thread - void ProcessPendingMessages(void); - // cSocketThreads::cCallback overrides: virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client -- cgit v1.2.3 From 259cf9f027adb41925e075799c7e46ccbcaec881 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 22:27:49 +0200 Subject: cEvent can now wait for the event with a specified timeout. --- source/OSSupport/Event.cpp | 104 +++++++++++++++++++++++++++++++++------------ source/OSSupport/Event.h | 10 +++++ 2 files changed, 88 insertions(+), 26 deletions(-) diff --git a/source/OSSupport/Event.cpp b/source/OSSupport/Event.cpp index 13b5c1d3f..f3c9053b1 100644 --- a/source/OSSupport/Event.cpp +++ b/source/OSSupport/Event.cpp @@ -15,7 +15,7 @@ cEvent::cEvent(void) { #ifdef _WIN32 - m_Event = CreateEvent( 0, FALSE, FALSE, 0 ); + m_Event = CreateEvent(NULL, FALSE, FALSE, NULL); if (m_Event == NULL) { LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError()); @@ -78,19 +78,19 @@ cEvent::~cEvent() void cEvent::Wait(void) { -#ifdef _WIN32 - DWORD res = WaitForSingleObject(m_Event, INFINITE); - if (res != WAIT_OBJECT_0) - { - LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); - } -#else - int res = sem_wait(m_Event); - if (res != 0 ) - { - LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); - } -#endif + #ifdef _WIN32 + DWORD res = WaitForSingleObject(m_Event, INFINITE); + if (res != WAIT_OBJECT_0) + { + LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); + } + #else + int res = sem_wait(m_Event); + if (res != 0 ) + { + LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); + } + #endif } @@ -99,18 +99,70 @@ void cEvent::Wait(void) void cEvent::Set(void) { -#ifdef _WIN32 - if (!SetEvent(m_Event)) - { - LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError()); - } -#else - int res = sem_post(m_Event); - if (res != 0) - { - LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); - } -#endif + #ifdef _WIN32 + if (!SetEvent(m_Event)) + { + LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError()); + } + #else + int res = sem_post(m_Event); + if (res != 0) + { + LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); + } + #endif +} + + + + + +cEvent::eWaitResult cEvent::Wait(int a_TimeoutMilliSec) +{ + #ifdef _WIN32 + DWORD res = WaitForSingleObject(m_Event, (DWORD)a_TimeoutMilliSec); + switch (res) + { + case WAIT_OBJECT_0: + { + // The semaphore was signalled + return wrSignalled; + } + case WAIT_TIMEOUT: + { + // The timeout was hit + return wrTimeout; + } + default: + { + LOGWARNING("cEvent: timed-waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError()); + return wrError; + } + } + #else + timespec timeout; + timeout.tv_sec = a_TimeoutMilliSec / 1000; + timeout.tv_nsec = (a_TimeoutMilliSec % 1000) * 1000000; + int res = sem_timedwait(m_Event, &timeout); + switch (res) + { + case 0: + { + // The semaphore was signalled + return wrSignalled; + } + case ETIMEDOUT: + { + // The timeout was hit + return wrTimeout; + } + default: + { + LOGWARNING("cEvent: timed-waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); + return wrError; + } + } + #endif } diff --git a/source/OSSupport/Event.h b/source/OSSupport/Event.h index 71f418c0c..803d73b7e 100644 --- a/source/OSSupport/Event.h +++ b/source/OSSupport/Event.h @@ -19,12 +19,22 @@ class cEvent { public: + enum eWaitResult + { + wrSignalled, + wrTimeout, + wrError, + } ; + cEvent(void); ~cEvent(); void Wait(void); void Set (void); + /// Waits for the semaphore with a timeout + eWaitResult Wait(int a_TimeoutMilliSec); + private: #ifdef _WIN32 -- cgit v1.2.3 From f93d13c41993ba86cad8303fe0b07ec2098dac39 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 22:36:34 +0200 Subject: Fixed world's a_Dt parameter getting time values in wrong units. --- source/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/World.cpp b/source/World.cpp index 5c3a24177..4cc130811 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -211,7 +211,7 @@ void cWorld::cTickThread::Execute(void) while (!m_ShouldTerminate) { clock_t Start = clock(); - m_World.Tick((float)(LastTime - Start) / CLOCKS_PER_SEC); + m_World.Tick((float)(1000 * (Start - LastTime)) / CLOCKS_PER_SEC); clock_t Now = clock(); if (Now - Start < ClocksPerTick) { -- cgit v1.2.3 From 50205bc4df3c272b88a5edd81a35ac0aca8213d5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 14 Aug 2013 22:39:12 +0200 Subject: Added simple deadlock detection code. This will assert and then deliberately crash the server once a deadlock is detected. For detection, only the world tick threads are considered, cWorld's m_WorldAge is checked periodically and if it doesn't increment for several seconds, a deadlock is reported. --- VC2008/MCServer.vcproj | 8 +++ source/DeadlockDetect.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++++ source/DeadlockDetect.h | 70 +++++++++++++++++++++ source/Root.cpp | 17 +++-- 4 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 source/DeadlockDetect.cpp create mode 100644 source/DeadlockDetect.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 4d850626d..0dcdeb3db 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -390,6 +390,14 @@ RelativePath="..\source\Cuboid.h" > + + + + diff --git a/source/DeadlockDetect.cpp b/source/DeadlockDetect.cpp new file mode 100644 index 000000000..960038f81 --- /dev/null +++ b/source/DeadlockDetect.cpp @@ -0,0 +1,155 @@ + +// DeadlockDetect.cpp + +// Declares the cDeadlockDetect class that tries to detect deadlocks and aborts the server when it detects one + +#include "Globals.h" +#include "DeadlockDetect.h" +#include "Root.h" +#include "World.h" + + + + + +/// Number of milliseconds per cycle +const int CYCLE_MILLISECONDS = 500; + +/// When the number of cycles for the same world age hits this value, it is considered a deadlock +const int NUM_CYCLES_LIMIT = 40; // 40 = twenty seconds + + + + + +cDeadlockDetect::cDeadlockDetect(void) : + super("DeadlockDetect") +{ +} + + + + + +bool cDeadlockDetect::Start(void) +{ + // Read the initial world data: + class cFillIn : + public cWorldListCallback + { + public: + cFillIn(cDeadlockDetect * a_Detect) : + m_Detect(a_Detect) + { + } + + virtual bool Item(cWorld * a_World) override + { + m_Detect->SetWorldAge(a_World->GetName(), a_World->GetWorldAge()); + return false; + } + + protected: + cDeadlockDetect * m_Detect; + } FillIn(this); + cRoot::Get()->ForEachWorld(FillIn); + return super::Start(); +} + + + + + +void cDeadlockDetect::Stop(void) +{ + m_EvtTerminate.Set(); + super::Stop(); +} + + + + + +void cDeadlockDetect::Execute(void) +{ + // Loop until the event is signalled + while (m_EvtTerminate.Wait(CYCLE_MILLISECONDS) == cEvent::wrTimeout) + { + // Check the world ages: + class cChecker : + public cWorldListCallback + { + public: + cChecker(cDeadlockDetect * a_Detect) : + m_Detect(a_Detect) + { + } + + protected: + cDeadlockDetect * m_Detect; + + virtual bool Item(cWorld * a_World) override + { + m_Detect->CheckWorldAge(a_World->GetName(), a_World->GetWorldAge()); + return false; + } + } Checker(this); + cRoot::Get()->ForEachWorld(Checker); + } // while (should run) +} + + + + + +void cDeadlockDetect::SetWorldAge(const AString & a_WorldName, Int64 a_Age) +{ + m_WorldAges[a_WorldName].m_Age = a_Age; + m_WorldAges[a_WorldName].m_NumCyclesSame = 0; +} + + + + + +void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age) +{ + WorldAges::iterator itr = m_WorldAges.find(a_WorldName); + if (itr == m_WorldAges.end()) + { + ASSERT(!"Unknown world in cDeadlockDetect"); + return; + } + if (itr->second.m_Age == a_Age) + { + itr->second.m_NumCyclesSame += 1; + if (itr->second.m_NumCyclesSame > NUM_CYCLES_LIMIT) + { + DeadlockDetected(); + return; + } + } + else + { + itr->second.m_Age = a_Age; + itr->second.m_NumCyclesSame = 0; + } +} + + + + + +void cDeadlockDetect::DeadlockDetected(void) +{ + ASSERT(!"Deadlock detected"); + + // TODO: Make a crashdump / coredump + + // Crash the server intentionally: + *((int *)0) = 0; +} + + + + diff --git a/source/DeadlockDetect.h b/source/DeadlockDetect.h new file mode 100644 index 000000000..bbd76826a --- /dev/null +++ b/source/DeadlockDetect.h @@ -0,0 +1,70 @@ + +// DeadlockDetect.h + +// Declares the cDeadlockDetect class that tries to detect deadlocks and aborts the server when it detects one + +/* +This class simply monitors each world's m_WorldAge, which is expected to grow on each tick. +If the world age doesn't grow for several seconds, it's either because the server is super-overloaded, +or because the world tick thread hangs in a deadlock. We presume the latter and therefore kill the server. +Once we learn to write crashdumps programmatically, we should do so just before killing, to enable debugging. +*/ + + + +#pragma once + +#include "OSSupport/IsThread.h" + + + + + +class cDeadlockDetect : + public cIsThread +{ + typedef cIsThread super; + +public: + cDeadlockDetect(void); + + /// Starts the detection. Hides cIsThread's Start, because we need some initialization + bool Start(void); + + /// Stops the detection. Hides cIsThread's Stop, because we need to signal m_EvtTerminate + void Stop(void); + +protected: + struct sWorldAge + { + /// Last m_WorldAge that has been detected in this world + Int64 m_Age; + + /// Number of cycles for which the age has been the same + int m_NumCyclesSame; + } ; + + /// Maps world name -> sWorldAge + typedef std::map WorldAges; + + WorldAges m_WorldAges; + + cEvent m_EvtTerminate; + + + // cIsThread overrides: + virtual void Execute(void) override; + + /// Sets the initial world age + void SetWorldAge(const AString & a_WorldName, Int64 a_Age); + + /// Checks if the world's age has changed, updates the world's stats; calls DeadlockDetected() if deadlock detected + void CheckWorldAge(const AString & a_WorldName, Int64 a_Age); + + /// Called when a deadlock is detected. Aborts the server. + void DeadlockDetected(void); +} ; + + + + diff --git a/source/Root.cpp b/source/Root.cpp index 166932cf2..07de0775c 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -16,6 +16,7 @@ #include "Chunk.h" #include "Protocol/ProtocolRecognizer.h" // for protocol version constants #include "CommandOutput.h" +#include "DeadlockDetect.h" #include "../iniFile/iniFile.h" @@ -90,6 +91,7 @@ void cRoot::InputThread(void * a_Params) void cRoot::Start(void) { + cDeadlockDetect dd; delete m_Log; m_Log = new cMCLogger(); @@ -162,6 +164,9 @@ void cRoot::Start(void) LOG("Starting worlds..."); StartWorlds(); + LOG("Starting deadlock detector..."); + dd.Start(); + LOG("Starting server..."); m_Server->Start(); @@ -183,17 +188,21 @@ void cRoot::Start(void) // Deallocate stuffs LOG("Shutting down server..."); - m_Server->Shutdown(); // This waits for threads to stop and d/c clients + m_Server->Shutdown(); + + LOG("Shutting down deadlock detector..."); + dd.Stop(); + LOG("Stopping world threads..."); StopWorlds(); + LOG("Stopping authenticator..."); m_Authenticator.Stop(); - LOG("Freeing MonsterConfig..."); - delete m_MonsterConfig; m_MonsterConfig = 0; + delete m_MonsterConfig; m_MonsterConfig = NULL; LOG("Stopping WebAdmin..."); - delete m_WebAdmin; m_WebAdmin = 0; + delete m_WebAdmin; m_WebAdmin = NULL; LOG("Unloading recipes..."); delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; delete m_CraftingRecipes; m_CraftingRecipes = NULL; -- cgit v1.2.3 From 0297cf548558a20e36acac3057728ad9a9aac234 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 Aug 2013 09:03:58 +0200 Subject: Updated CryptoPP to 5.6.2 --- CryptoPP/License.txt | 69 ++++++++++++++++++++++----------------------------- CryptoPP/Readme.txt | 12 +++++++-- CryptoPP/algebra.cpp | 32 ++++++++++++------------ CryptoPP/config.h | 2 +- CryptoPP/cryptlib.h | 4 +-- CryptoPP/dsa.cpp | 56 ----------------------------------------- CryptoPP/gfpcrypt.cpp | 38 ++++++++++++++-------------- CryptoPP/gfpcrypt.h | 48 +++++++++++++++-------------------- CryptoPP/misc.h | 2 +- CryptoPP/osrng.cpp | 29 +++++++++++++++++++--- CryptoPP/queue.h | 1 + CryptoPP/rw.h | 10 ++++++++ CryptoPP/validate.h | 2 +- 13 files changed, 134 insertions(+), 171 deletions(-) diff --git a/CryptoPP/License.txt b/CryptoPP/License.txt index 043e4b698..c5d3f34b1 100644 --- a/CryptoPP/License.txt +++ b/CryptoPP/License.txt @@ -1,4 +1,4 @@ -Compilation Copyright (c) 1995-2010 by Wei Dai. All rights reserved. +Compilation Copyright (c) 1995-2013 by Wei Dai. All rights reserved. This copyright applies only to this software distribution package as a compilation, and does not imply a copyright on any particular file in the package. @@ -21,42 +21,31 @@ Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp Richard De Moliner - safer.cpp Matthew Skala - twofish.cpp Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp - -Permission to use, copy, modify, and distribute this compilation for -any purpose, including commercial applications, is hereby granted -without fee, subject to the following restrictions: - -1. Any copy or modification of this compilation in any form, except -in object code form as part of an application software, must include -the above copyright notice and this license. - -2. Users of this software agree that any modification or extension -they provide to Wei Dai will be considered public domain and not -copyrighted unless it includes an explicit copyright notice. - -3. Wei Dai makes no warranty or representation that the operation of the -software in this compilation will be error-free, and Wei Dai is under no -obligation to provide any services, by way of maintenance, update, or -otherwise. THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS" -WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR -DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -4. Users will not use Wei Dai or any other contributor's name in any -publicity or advertising, without prior written consent in each case. - -5. Export of this software from the United States may require a -specific license from the United States Government. It is the -responsibility of any person or organization contemplating export -to obtain such a license before exporting. - -6. Certain parts of this software may be protected by patents. It -is the users' responsibility to obtain the appropriate -licenses before using those parts. - -If this compilation is used in object code form in an application -software, acknowledgement of the author is not required but would be -appreciated. The contribution of any useful modifications or extensions -to Wei Dai is not required but would also be appreciated. +Ronny Van Keer - sha3.cpp + +The Crypto++ Library (as a compilation) is currently licensed under the Boost +Software License 1.0 (http://www.boost.org/users/license.html). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/CryptoPP/Readme.txt b/CryptoPP/Readme.txt index 2f04e9f28..5f3b4525d 100644 --- a/CryptoPP/Readme.txt +++ b/CryptoPP/Readme.txt @@ -1,5 +1,5 @@ Crypto++: a C++ Class Library of Cryptographic Schemes -Version 5.6.2 (in development) +Version 5.6.2 - 2/20/2013 Crypto++ Library is a free C++ class library of cryptographic schemes. Currently the library contains the following algorithms: @@ -24,7 +24,7 @@ Currently the library contains the following algorithms: Two-Track-MAC SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and - hash functions SHA-512), Tiger, WHIRLPOOL, RIPEMD-128, + hash functions SHA-512), SHA-3, Tiger, WHIRLPOOL, RIPEMD-128, RIPEMD-256, RIPEMD-160, RIPEMD-320 RSA, DSA, ElGamal, Nyberg-Rueppel (NR), @@ -441,4 +441,12 @@ the mailing list. - ported to MSVC 2010, GCC 4.5.1, Sun Studio 12u1, C++Builder 2010, Intel C++ Compiler 11.1 - renamed the MSVC DLL project to "cryptopp" for compatibility with MSVC 2010 +5.6.2 - changed license to Boost Software License 1.0 + - added SHA-3 (Keccak) + - updated DSA to FIPS 186-3 (see DSA2 class) + - fixed Blowfish minimum keylength to be 4 bytes (32 bits) + - fixed Salsa validation failure when compiling with GCC 4.6 + - fixed infinite recursion when on x64, assembly disabled, and no AESNI + - ported to MSVC 2012, GCC 4.7, Clang 3.2, Solaris Studio 12.3, Intel C++ Compiler 13.0 + Written by Wei Dai diff --git a/CryptoPP/algebra.cpp b/CryptoPP/algebra.cpp index b8818e6af..958e63701 100644 --- a/CryptoPP/algebra.cpp +++ b/CryptoPP/algebra.cpp @@ -14,42 +14,42 @@ NAMESPACE_BEGIN(CryptoPP) template const T& AbstractGroup::Double(const Element &a) const { - return Add(a, a); + return this->Add(a, a); } template const T& AbstractGroup::Subtract(const Element &a, const Element &b) const { // make copy of a in case Inverse() overwrites it Element a1(a); - return Add(a1, Inverse(b)); + return this->Add(a1, Inverse(b)); } template T& AbstractGroup::Accumulate(Element &a, const Element &b) const { - return a = Add(a, b); + return a = this->Add(a, b); } template T& AbstractGroup::Reduce(Element &a, const Element &b) const { - return a = Subtract(a, b); + return a = this->Subtract(a, b); } template const T& AbstractRing::Square(const Element &a) const { - return Multiply(a, a); + return this->Multiply(a, a); } template const T& AbstractRing::Divide(const Element &a, const Element &b) const { // make copy of a in case MultiplicativeInverse() overwrites it Element a1(a); - return Multiply(a1, MultiplicativeInverse(b)); + return this->Multiply(a1, this->MultiplicativeInverse(b)); } template const T& AbstractEuclideanDomain::Mod(const Element &a, const Element &b) const { Element q; - DivisionAlgorithm(result, q, a, b); + this->DivisionAlgorithm(result, q, a, b); return result; } @@ -60,7 +60,7 @@ template const T& AbstractEuclideanDomain::Gcd(const Element &a, co while (!this->Equal(g[i1], this->Identity())) { - g[i2] = Mod(g[i0], g[i1]); + g[i2] = this->Mod(g[i0], g[i1]); unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; } @@ -74,7 +74,7 @@ template const typename QuotientRing::Element& QuotientRing::Mul Element y; unsigned int i0=0, i1=1, i2=2; - while (!Equal(g[i1], Identity())) + while (!this->Equal(g[i1], this->Identity())) { // y = g[i0] / g[i1]; // g[i2] = g[i0] % g[i1]; @@ -90,7 +90,7 @@ template const typename QuotientRing::Element& QuotientRing::Mul template T AbstractGroup::ScalarMultiply(const Element &base, const Integer &exponent) const { Element result; - SimultaneousMultiply(&result, base, &exponent, 1); + this->SimultaneousMultiply(&result, base, &exponent, 1); return result; } @@ -98,7 +98,7 @@ template T AbstractGroup::CascadeScalarMultiply(const Element &x, c { const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); if (expLen==0) - return Identity(); + return this->Identity(); const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); const unsigned tableSize = 1< T AbstractGroup::CascadeScalarMultiply(const Element &x, c powerTable[1] = x; powerTable[tableSize] = y; if (w==1) - powerTable[3] = Add(x,y); + powerTable[3] = this->Add(x,y); else { - powerTable[2] = Double(x); - powerTable[2*tableSize] = Double(y); + powerTable[2] = this->Double(x); + powerTable[2*tableSize] = this->Double(y); unsigned i, j; @@ -157,12 +157,12 @@ template T AbstractGroup::CascadeScalarMultiply(const Element &x, c else { while (squaresBefore--) - result = Double(result); + result = this->Double(result); if (power1 || power2) Accumulate(result, powerTable[(power2<Double(result); power1 = power2 = 0; } } diff --git a/CryptoPP/config.h b/CryptoPP/config.h index ba7c00110..edbfd00ef 100644 --- a/CryptoPP/config.h +++ b/CryptoPP/config.h @@ -348,7 +348,7 @@ NAMESPACE_END #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS #endif -#define CRYPTOPP_VERSION 561 +#define CRYPTOPP_VERSION 562 // ***************** determine availability of OS features ******************** diff --git a/CryptoPP/cryptlib.h b/CryptoPP/cryptlib.h index 0ad18de80..406872232 100644 --- a/CryptoPP/cryptlib.h +++ b/CryptoPP/cryptlib.h @@ -4,7 +4,7 @@ classes that provide a uniform interface to this library. */ -/*! \mainpage Crypto++ Library 5.6.1 API Reference +/*! \mainpage Crypto++ Library 5.6.2 API Reference
Abstract Base Classes
cryptlib.h @@ -25,7 +25,7 @@
Public Key Cryptosystems
DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
Public Key Signature Schemes
- DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN + DSA2, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN
Key Agreement
#DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
Algebraic Structures
diff --git a/CryptoPP/dsa.cpp b/CryptoPP/dsa.cpp index ac9e1f8c6..5aace4857 100644 --- a/CryptoPP/dsa.cpp +++ b/CryptoPP/dsa.cpp @@ -58,62 +58,6 @@ size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFo return (size_t)sink.TotalPutLength(); } -bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter, - Integer &p, unsigned int L, Integer &q, bool useInputCounterValue) -{ - assert(g%8 == 0); - - SHA sha; - SecByteBlock seed(seedIn, g/8); - SecByteBlock U(SHA::DIGESTSIZE); - SecByteBlock temp(SHA::DIGESTSIZE); - SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE); - const int n = (L-1) / 160; - const int b = (L-1) % 160; - Integer X; - - sha.CalculateDigest(U, seed, g/8); - - for (int i=g/8-1, carry=true; i>=0 && carry; i--) - carry=!++seed[i]; - - sha.CalculateDigest(temp, seed, g/8); - xorbuf(U, temp, SHA::DIGESTSIZE); - - U[0] |= 0x80; - U[SHA::DIGESTSIZE-1] |= 1; - q.Decode(U, SHA::DIGESTSIZE); - - if (!IsPrime(q)) - return false; - - int counterEnd = useInputCounterValue ? counter+1 : 4096; - - for (int c = 0; c < counterEnd; c++) - { - for (int k=0; k<=n; k++) - { - for (int i=g/8-1, carry=true; i>=0 && carry; i--) - carry=!++seed[i]; - if (!useInputCounterValue || c == counter) - sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8); - } - if (!useInputCounterValue || c == counter) - { - W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80; - X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8); - p = X-((X % (2*q))-1); - - if (p.GetBit(L-1) && IsPrime(p)) - { - counter = c; - return true; - } - } - } - return false; -} - NAMESPACE_END #endif diff --git a/CryptoPP/gfpcrypt.cpp b/CryptoPP/gfpcrypt.cpp index 6d9ffcebd..e293fc598 100644 --- a/CryptoPP/gfpcrypt.cpp +++ b/CryptoPP/gfpcrypt.cpp @@ -30,39 +30,37 @@ void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const Na if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) { q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + Initialize(p, q, g); } else { - int modulusSize = 1024; + int modulusSize = 1024, defaultSubgroupOrderSize; alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - if (!DSA::IsValidPrimeLength(modulusSize)) - throw InvalidArgument("DSA: not a valid prime length"); - - SecByteBlock seed(SHA::DIGESTSIZE); - Integer h; - int c; - - do + switch (modulusSize) { - rng.GenerateBlock(seed, SHA::DIGESTSIZE); - } while (!DSA::GeneratePrimes(seed, SHA::DIGESTSIZE*8, c, p, modulusSize, q)); + case 1024: + defaultSubgroupOrderSize = 160; + break; + case 2048: + defaultSubgroupOrderSize = 224; + break; + case 3072: + defaultSubgroupOrderSize = 256; + break; + default: + throw InvalidArgument("DSA: not a valid prime length"); + } - do - { - h.Randomize(rng, 2, p-2); - g = a_exp_b_mod_c(h, (p-1)/q, p); - } while (g <= 1); + DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false))); } - - Initialize(p, q, g); } bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const { bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); - pass = pass && DSA::IsValidPrimeLength(GetModulus().BitCount()); - pass = pass && GetSubgroupOrder().BitCount() == 160; + int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount(); + pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256)); return pass; } diff --git a/CryptoPP/gfpcrypt.h b/CryptoPP/gfpcrypt.h index 5e9c635d6..7af993fb3 100644 --- a/CryptoPP/gfpcrypt.h +++ b/CryptoPP/gfpcrypt.h @@ -369,51 +369,43 @@ public: /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) + {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} + + enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; }; -struct DSA; +template +class DSA2; //! DSA keys struct DL_Keys_DSA { typedef DL_PublicKey_GFP PublicKey; - typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA> PrivateKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 > PrivateKey; }; -//! DSA -struct CRYPTOPP_DLL DSA : public DL_SS< +//! DSA, as specified in FIPS 186-3 +// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class) +template +class DSA2 : public DL_SS< DL_Keys_DSA, DL_Algorithm_GDSA, DL_SignatureMessageEncodingMethod_DSA, - SHA, - DSA> + H, + DSA2 > { - static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA";} - - //! Generate DSA primes according to NIST standard - /*! Both seedLength and primeLength are in bits, but seedLength should - be a multiple of 8. - If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output - */ - static bool CRYPTOPP_API GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter, - Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false); - - static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) - {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} - - //! FIPS 186-2 Change Notice 1 changed the minimum modulus length to 1024 - enum { -#if (DSA_1024_BIT_MODULUS_ONLY) - MIN_PRIME_LENGTH = 1024, -#else - MIN_PRIME_LENGTH = 512, -#endif - MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64}; +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} }; +//! DSA with SHA-1, typedef'd for backwards compatibility +typedef DSA2 DSA; + CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP; CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 >; //! the XOR encryption method, for use with DL-based cryptosystems template diff --git a/CryptoPP/misc.h b/CryptoPP/misc.h index 7f32b860b..2b326dd60 100644 --- a/CryptoPP/misc.h +++ b/CryptoPP/misc.h @@ -141,7 +141,7 @@ const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const // ************** misc functions *************** -#if (!__STDC_WANT_SECURE_LIB__) +#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) { if (count > sizeInBytes) diff --git a/CryptoPP/osrng.cpp b/CryptoPP/osrng.cpp index fa6dd36dd..76e486b4e 100644 --- a/CryptoPP/osrng.cpp +++ b/CryptoPP/osrng.cpp @@ -83,8 +83,22 @@ void NonblockingRng::GenerateBlock(byte *output, size_t size) if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output)) throw OS_RNG_Err("CryptGenRandom"); #else - if (read(m_fd, output, size) != size) - throw OS_RNG_Err("read /dev/urandom"); + while (size) + { + ssize_t len = read(m_fd, output, size); + + if (len < 0) + { + // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read /dev/urandom"); + + continue; + } + + output += len; + size -= len; + } #endif } @@ -119,10 +133,17 @@ void BlockingRng::GenerateBlock(byte *output, size_t size) while (size) { // on some systems /dev/random will block until all bytes - // are available, on others it will returns immediately + // are available, on others it returns immediately ssize_t len = read(m_fd, output, size); if (len < 0) - throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + { + // /dev/random reads CAN give EAGAIN errors! (maybe EINTR as well) + if (errno != EINTR && errno != EAGAIN) + throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + + continue; + } + size -= len; output += len; if (size) diff --git a/CryptoPP/queue.h b/CryptoPP/queue.h index 75f7807fd..ab89dbdf1 100644 --- a/CryptoPP/queue.h +++ b/CryptoPP/queue.h @@ -58,6 +58,7 @@ public: ByteQueue & operator=(const ByteQueue &rhs); bool operator==(const ByteQueue &rhs) const; + bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);} byte operator[](lword i) const; void swap(ByteQueue &rhs); diff --git a/CryptoPP/rw.h b/CryptoPP/rw.h index ec8b8507b..6820251e8 100644 --- a/CryptoPP/rw.h +++ b/CryptoPP/rw.h @@ -22,6 +22,11 @@ public: void BERDecode(BufferedTransformation &bt); void DEREncode(BufferedTransformation &bt) const; + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + Integer ApplyFunction(const Integer &x) const; Integer PreimageBound() const {return ++(m_n>>1);} Integer ImageBound() const {return m_n;} @@ -52,6 +57,11 @@ public: void BERDecode(BufferedTransformation &bt); void DEREncode(BufferedTransformation &bt) const; + void Save(BufferedTransformation &bt) const + {DEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; // GeneratibleCryptoMaterial diff --git a/CryptoPP/validate.h b/CryptoPP/validate.h index 685340775..0ab23cba3 100644 --- a/CryptoPP/validate.h +++ b/CryptoPP/validate.h @@ -76,6 +76,6 @@ bool ValidateECDSA(); bool ValidateESIGN(); CryptoPP::RandomNumberGenerator & GlobalRNG(); -bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs); +bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs, bool thorough=true); #endif -- cgit v1.2.3 From 0aace84516c88d49c0ba0cfe746344b48d153e34 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 Aug 2013 09:20:50 +0200 Subject: Updated the makefile to disable assembly for clang. You need to set a flag manually, "disableasm=1" on the commandline. --- GNUmakefile | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 277308e08..f139b3d39 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -12,6 +12,8 @@ # Usage: # To make a release build, call "make release=1" # To make a debug build, call "make" +# To make a 32-bit build on 64-bit OS, pass the addm32=1 flag +# To build with clang, you need to add disableasm=1 flag # ################################################### @@ -98,10 +100,9 @@ endif -################ +################################################### # 32-bit build override in 64-bit build environments -# - so that BearBin doesn't need to modify his makefile after each makefile change :) -################ + ifeq ($(addm32),1) CC_OPTIONS += -m32 CXX_OPTIONS += -m32 @@ -110,6 +111,21 @@ endif + + + +################################################### +# Clang doesn't seem to support CryptoPP's assembly mode, disable it for now (CryptoPP 5.6.2) + +ifeq ($(disableasm),1) + CC_OPTIONS += -DCRYPTOPP_DISABLE_ASM + CXX_OPTIONS += -DCRYPTOPP_DISABLE_ASM +endif + + + + + ################################################### # INCLUDE directories for MCServer # -- cgit v1.2.3 From 28de751f2c5d3d456b5de2691464dfe6a814e178 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 Aug 2013 13:05:24 +0200 Subject: Attempting to fix CentOS / gcc 4.4.7 compilation problem. Reported by ThijsD in the forum http://forum.mc-server.org/showthread.php?tid=1220 --- source/LuaState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/LuaState.cpp b/source/LuaState.cpp index 6de8f3dc1..d1a8613b0 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -32,7 +32,7 @@ extern "C" -const cLuaState::cRet cLuaState::Return; +const cLuaState::cRet cLuaState::Return = {}; -- cgit v1.2.3 From 18fcab06ce8bdff93e87c2fbcc6ec7898f74fedb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 15 Aug 2013 13:50:49 +0200 Subject: Added Luksor to contributors list. --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 8ac48e880..45ff948a0 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -11,5 +11,6 @@ Lapayo rs2k Duralex mtilden +Luksor If you feel you have contributed enough to be included in this list, just put in a PR including yourself. -- cgit v1.2.3 From 1c2140dd4de149e55ece23b64f845d30d22b6653 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 Aug 2013 17:18:17 +0200 Subject: Fixed the Reload and Save-all console commands. They were broken by the PerWorldThreads update removing cServer:BroadcastMessage() and cServer:SendMessage() --- MCServer/Plugins/Core/console.lua | 81 +++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/MCServer/Plugins/Core/console.lua b/MCServer/Plugins/Core/console.lua index 669d7c9cb..8ae8cb675 100644 --- a/MCServer/Plugins/Core/console.lua +++ b/MCServer/Plugins/Core/console.lua @@ -21,9 +21,12 @@ function InitConsoleCommands() PluginMgr:BindConsoleCommand("setversion", HandleConsoleVersion, " ~ Sets server version reported to 1.4+ clients"); PluginMgr:BindConsoleCommand("unban", HandleConsoleUnban, " ~ Unbans a player by name"); PluginMgr:BindConsoleCommand("unload", HandleConsoleUnload, " - Unloads all unused chunks"); - end + + + + function HandleConsoleGive(Split) -- Make sure there are a correct number of arguments. @@ -80,9 +83,12 @@ function HandleConsoleGive(Split) end return true - end + + + + function HandleConsoleBan(Split) if (#Split < 2) then return true, "Usage: ban [Player] "; @@ -108,6 +114,10 @@ function HandleConsoleBan(Split) return true end + + + + function HandleConsoleUnban(Split) if #Split < 2 then @@ -123,9 +133,12 @@ function HandleConsoleUnban(Split) local Server = cRoot:Get():GetServer() return true, "Unbanned " .. Split[2] - end + + + + function HandleConsoleBanList(Split) if (#Split == 1) then return true, BanListByName(); @@ -138,6 +151,10 @@ function HandleConsoleBanList(Split) return true, "Unknown banlist subcommand"; end + + + + function HandleConsoleHelp(Split) local Commands = {}; -- {index => {"Command", "HelpString"} } local MaxLength = 0; @@ -166,6 +183,10 @@ function HandleConsoleHelp(Split) return true, Out; end + + + + function HandleConsoleList(Split) -- Get a list of all players, one playername per line local Out = ""; @@ -181,6 +202,10 @@ function HandleConsoleList(Split) return true, Out; end + + + + function HandleConsoleListGroups(Split) -- Read the groups.ini file: local GroupsIni = cIniFile("groups.ini"); @@ -201,6 +226,10 @@ function HandleConsoleListGroups(Split) return true, Out; end + + + + function HandleConsoleNumChunks(Split) local Output = {}; local AddNumChunks = function(World) @@ -220,6 +249,10 @@ function HandleConsoleNumChunks(Split) return true, Out; end + + + + function HandleConsolePlayers(Split) local PlayersInWorlds = {}; -- "WorldName" => [players array] local AddToTable = function(Player) @@ -243,6 +276,10 @@ function HandleConsolePlayers(Split) return true, Out; end + + + + function HandleConsoleVersion(Split) if (#Split == 1) then -- Display current version: @@ -256,6 +293,10 @@ function HandleConsoleVersion(Split) return true, "Primary server version is now #" .. Version .. ", " .. cRoot:GetProtocolVersionTextFromInt(Version); end + + + + function HandleConsoleRank(Split) if (Split[2] == nil) or (Split[3] == nil) then return true, "Usage: /rank [Player] [Group]"; @@ -301,20 +342,38 @@ function HandleConsoleRank(Split) return true, Out .. "Player " .. Split[2] .. " was moved to " .. Split[3]; end + + + + function HandleConsoleReload(Split) - Server = cRoot:Get():GetServer(); - Server:SendMessage(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Reloading all plugins!"); + cRoot:Get():ForEachWorld( + function (a_World) + a_World:BroadcastChat(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Reloading all plugins!"); + end + ) cPluginManager:Get():ReloadPlugins(); return true; end + + + + function HandleConsoleSaveAll(Split) - Server = cRoot:Get():GetServer(); - Server:SendMessage(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Saving all chunks!"); + cRoot:Get():ForEachWorld( + function (a_World) + a_World:BroadcastChat(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Saving all chunks!"); + end + ) cRoot:Get():SaveAllChunks(); return true; end + + + + function HandleConsoleSay(Split) table.remove(Split, 1); local Message = ""; @@ -326,6 +385,10 @@ function HandleConsoleSay(Split) return true; end + + + + function HandleConsoleUnload(Split) local UnloadChunks = function(World) World:UnloadUnusedChunks(); @@ -336,3 +399,7 @@ function HandleConsoleUnload(Split) Out = Out .. "Num loaded chunks after: " .. cRoot:Get():GetTotalChunkCount(); return true, Out; end + + + + -- cgit v1.2.3 From 69fcf3188a17490fa229021baef462cf006a8ac2 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Thu, 15 Aug 2013 18:11:35 +0100 Subject: Changed a line, new PR system test. --- CONTRIBUTORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 45ff948a0..781f973ce 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -13,4 +13,4 @@ Duralex mtilden Luksor -If you feel you have contributed enough to be included in this list, just put in a PR including yourself. +Please add yourself to this list if you contribute to MCServer. -- cgit v1.2.3 From 7acb665f25a073bf9eb3ca0f8cced0f1caea1dfd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 Aug 2013 22:12:57 +0200 Subject: Exported cWorld:DoExplosionAt() to Lua API. --- source/Bindings.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/World.h | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 1ebd858e3..5684b59f7 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/14/13 19:48:00. +** Generated automatically by tolua++-1.0.92 on 08/15/13 22:11:03. */ #ifndef __cplusplus @@ -12895,6 +12895,51 @@ static int tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: DoExplosiontAt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DoExplosiontAt00 +static int tolua_AllToLua_cWorld_DoExplosiontAt00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isboolean(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isuserdata(tolua_S,8,0,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + double a_ExplosionSize = ((double) tolua_tonumber(tolua_S,2,0)); + double a_BlockX = ((double) tolua_tonumber(tolua_S,3,0)); + double a_BlockY = ((double) tolua_tonumber(tolua_S,4,0)); + double a_BlockZ = ((double) tolua_tonumber(tolua_S,5,0)); + bool a_CanCauseFire = ((bool) tolua_toboolean(tolua_S,6,0)); + eExplosionSource a_Source = ((eExplosionSource) (int) tolua_tonumber(tolua_S,7,0)); + void* a_SourceData = ((void*) tolua_touserdata(tolua_S,8,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DoExplosiontAt'", NULL); +#endif + { + self->DoExplosiontAt(a_ExplosionSize,a_BlockX,a_BlockY,a_BlockZ,a_CanCauseFire,a_Source,a_SourceData); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DoExplosiontAt'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetSignLines of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSignLines00 static int tolua_AllToLua_cWorld_GetSignLines00(lua_State* tolua_S) @@ -29776,6 +29821,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); tolua_function(tolua_S,"WakeUpSimulators",tolua_AllToLua_cWorld_WakeUpSimulators00); tolua_function(tolua_S,"WakeUpSimulatorsInArea",tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00); + tolua_function(tolua_S,"DoExplosiontAt",tolua_AllToLua_cWorld_DoExplosiontAt00); tolua_function(tolua_S,"GetSignLines",tolua_AllToLua_cWorld_GetSignLines00); tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); diff --git a/source/Bindings.h b/source/Bindings.h index 583017a88..eb2146715 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/14/13 19:48:00. +** Generated automatically by tolua++-1.0.92 on 08/15/13 22:11:04. */ /* Exported function */ diff --git a/source/World.h b/source/World.h index 4f1e942e4..8525eebe5 100644 --- a/source/World.h +++ b/source/World.h @@ -403,7 +403,7 @@ public: | esWitherBirth | TBD | | esPlugin | void * | */ - void DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); + void DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export /// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp -- cgit v1.2.3 From 98d574f05ea46763fc9e762b0719ab3ef2271230 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 09:20:05 +0200 Subject: No more Core in the MCServer repo --- MCServer/Plugins/.gitignore | 1 + MCServer/Plugins/Core/README.md | 72 --- MCServer/Plugins/Core/back.lua | 10 - MCServer/Plugins/Core/ban-unban.lua | 49 -- MCServer/Plugins/Core/clear.lua | 25 - MCServer/Plugins/Core/console.lua | 405 ------------ MCServer/Plugins/Core/do.lua | 29 - MCServer/Plugins/Core/functions.lua | 162 ----- MCServer/Plugins/Core/give.lua | 66 -- MCServer/Plugins/Core/gm.lua | 11 - MCServer/Plugins/Core/help.lua | 43 -- MCServer/Plugins/Core/item.lua | 26 - MCServer/Plugins/Core/itemrepair.lua | 202 ------ MCServer/Plugins/Core/kick.lua | 19 - MCServer/Plugins/Core/kill.lua | 34 - MCServer/Plugins/Core/locate.lua | 4 - MCServer/Plugins/Core/main.lua | 198 ------ MCServer/Plugins/Core/me.lua | 20 - MCServer/Plugins/Core/motd.lua | 44 -- MCServer/Plugins/Core/onbreakplaceblock.lua | 119 ---- MCServer/Plugins/Core/ondeath.lua | 56 -- MCServer/Plugins/Core/onjoinleave.lua | 23 - MCServer/Plugins/Core/onlogin.lua | 17 - MCServer/Plugins/Core/plugins.lua | 17 - MCServer/Plugins/Core/portal-worlds.lua | 41 -- MCServer/Plugins/Core/rank-groups.lua | 63 -- MCServer/Plugins/Core/regen.lua | 20 - MCServer/Plugins/Core/save-reload-stop.lua | 28 - MCServer/Plugins/Core/spawn.lua | 9 - MCServer/Plugins/Core/teleport.lua | 74 --- MCServer/Plugins/Core/tell.lua | 37 -- MCServer/Plugins/Core/time.lua | 26 - MCServer/Plugins/Core/top.lua | 13 - MCServer/Plugins/Core/viewdistance.lua | 12 - MCServer/Plugins/Core/weather.lua | 33 - MCServer/Plugins/Core/web_chat.lua | 157 ----- MCServer/Plugins/Core/web_manageplugins.lua | 157 ----- MCServer/Plugins/Core/web_manageserver.lua | 35 - MCServer/Plugins/Core/web_permissions.lua | 134 ---- MCServer/Plugins/Core/web_playerlist.lua | 38 -- MCServer/Plugins/Core/web_serversettings.lua | 920 --------------------------- MCServer/Plugins/Core/web_whitelist.lua | 79 --- MCServer/Plugins/Core/worldlimiter.lua | 22 - 43 files changed, 1 insertion(+), 3549 deletions(-) create mode 100644 MCServer/Plugins/.gitignore delete mode 100644 MCServer/Plugins/Core/README.md delete mode 100644 MCServer/Plugins/Core/back.lua delete mode 100644 MCServer/Plugins/Core/ban-unban.lua delete mode 100644 MCServer/Plugins/Core/clear.lua delete mode 100644 MCServer/Plugins/Core/console.lua delete mode 100644 MCServer/Plugins/Core/do.lua delete mode 100644 MCServer/Plugins/Core/functions.lua delete mode 100644 MCServer/Plugins/Core/give.lua delete mode 100644 MCServer/Plugins/Core/gm.lua delete mode 100644 MCServer/Plugins/Core/help.lua delete mode 100644 MCServer/Plugins/Core/item.lua delete mode 100644 MCServer/Plugins/Core/itemrepair.lua delete mode 100644 MCServer/Plugins/Core/kick.lua delete mode 100644 MCServer/Plugins/Core/kill.lua delete mode 100644 MCServer/Plugins/Core/locate.lua delete mode 100644 MCServer/Plugins/Core/main.lua delete mode 100644 MCServer/Plugins/Core/me.lua delete mode 100644 MCServer/Plugins/Core/motd.lua delete mode 100644 MCServer/Plugins/Core/onbreakplaceblock.lua delete mode 100644 MCServer/Plugins/Core/ondeath.lua delete mode 100644 MCServer/Plugins/Core/onjoinleave.lua delete mode 100644 MCServer/Plugins/Core/onlogin.lua delete mode 100644 MCServer/Plugins/Core/plugins.lua delete mode 100644 MCServer/Plugins/Core/portal-worlds.lua delete mode 100644 MCServer/Plugins/Core/rank-groups.lua delete mode 100644 MCServer/Plugins/Core/regen.lua delete mode 100644 MCServer/Plugins/Core/save-reload-stop.lua delete mode 100644 MCServer/Plugins/Core/spawn.lua delete mode 100644 MCServer/Plugins/Core/teleport.lua delete mode 100644 MCServer/Plugins/Core/tell.lua delete mode 100644 MCServer/Plugins/Core/time.lua delete mode 100644 MCServer/Plugins/Core/top.lua delete mode 100644 MCServer/Plugins/Core/viewdistance.lua delete mode 100644 MCServer/Plugins/Core/weather.lua delete mode 100644 MCServer/Plugins/Core/web_chat.lua delete mode 100644 MCServer/Plugins/Core/web_manageplugins.lua delete mode 100644 MCServer/Plugins/Core/web_manageserver.lua delete mode 100644 MCServer/Plugins/Core/web_permissions.lua delete mode 100644 MCServer/Plugins/Core/web_playerlist.lua delete mode 100644 MCServer/Plugins/Core/web_serversettings.lua delete mode 100644 MCServer/Plugins/Core/web_whitelist.lua delete mode 100644 MCServer/Plugins/Core/worldlimiter.lua diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore new file mode 100644 index 000000000..a9f9bd175 --- /dev/null +++ b/MCServer/Plugins/.gitignore @@ -0,0 +1 @@ +Core \ No newline at end of file diff --git a/MCServer/Plugins/Core/README.md b/MCServer/Plugins/Core/README.md deleted file mode 100644 index 04cba0aa2..000000000 --- a/MCServer/Plugins/Core/README.md +++ /dev/null @@ -1,72 +0,0 @@ -MCServer Core Plugin -==================== - -The Core plugin for MCServer provides the default utility commands and also a lot of WebAdmin goodness. - -Commands --------- - - * /back - * /ban - * /clear - * /downfall - * /give - * /gm - * /groups - * /help - * /i - * /item - * /kill - * /kick - * /locate - * /me - * /motd - * /plugins - * /portal - * /rank - * /regen - * /reload - * /save-all - * /spawn - * /stop - * /time - * /top - * /tp - * /tpa - * /tpaccept - * /unban - * /viewdistance - * /worlds - -**Also, console commands:** - - * ban - * banlist - * getversion - * help - * list - * listgroups - * numchunks - * players - * rank - * reload - * say - * setversion - * unban - * unload - -Contributors ------------- - -FakeTruth -xoft -tigerw -bearbin -tonibm19 - -(If you want your name here, please submit a PR after you've done your contributions.) - -How to Use ----------- - -Core should be installed in MCServer by default. diff --git a/MCServer/Plugins/Core/back.lua b/MCServer/Plugins/Core/back.lua deleted file mode 100644 index 201e0bb42..000000000 --- a/MCServer/Plugins/Core/back.lua +++ /dev/null @@ -1,10 +0,0 @@ -function HandleBackCommand( Split, Player ) - if BackCoords[Player:GetName()] == nil then - SendMessageFailure(Player, "No known last position") - return true - else - Player:TeleportToCoords(BackCoords[Player:GetName()].x, BackCoords[Player:GetName()].y, BackCoords[Player:GetName()].z) - SendMessageSuccess(Player, "Teleported back to your last known position") - end - return true -end diff --git a/MCServer/Plugins/Core/ban-unban.lua b/MCServer/Plugins/Core/ban-unban.lua deleted file mode 100644 index 1db99fda5..000000000 --- a/MCServer/Plugins/Core/ban-unban.lua +++ /dev/null @@ -1,49 +0,0 @@ -function HandleBanCommand( Split, Player ) - - if( #Split < 2 ) then - SendMessage( Player, "Usage: /ban [Player] " ) - return true - end - - local Reason = cChatColor.Red .. "You have been banned." .. cChatColor.White .. " Did you do something illegal?" - if( #Split > 2 ) then - Reason = table.concat( Split, " ", 3 ) - end - - if KickPlayer(Split[2], Reason) == false then - BannedPlayersIni:DeleteValue( "Banned", Split[2] ) - BannedPlayersIni:SetValueB( "Banned", Split[2], true ) - BannedPlayersIni:WriteFile() - SendMessageFailure( Player, "Could not find player, but banned anyway" ) - else - BannedPlayersIni:DeleteValue( "Banned", Split[2] ) - BannedPlayersIni:SetValueB( "Banned", Split[2], true ) - BannedPlayersIni:WriteFile() - SendMessageSuccess( Player, "Successfully kicked and banned player" ) - end - return true - -end - -function HandleUnbanCommand( Split, Player ) - - if( #Split < 2 ) then - SendMessage( Player, "Usage: /unban [Player]" ) - return true - end - - if( BannedPlayersIni:GetValueB("Banned", Split[2], false) == false ) then - SendMessageFailure( Player, "Player is not banned!" ) - return true - end - - BannedPlayersIni:DeleteValue("Banned", Split[2]) - BannedPlayersIni:SetValueB("Banned", Split[2], false) - BannedPlayersIni:WriteFile() - - LOGINFO( Player:GetName() .. " is unbanning " .. Split[2] ) - SendMessageSuccess( Player, "Unbanning " .. Split[2] ) - - return true - -end diff --git a/MCServer/Plugins/Core/clear.lua b/MCServer/Plugins/Core/clear.lua deleted file mode 100644 index aae2e897e..000000000 --- a/MCServer/Plugins/Core/clear.lua +++ /dev/null @@ -1,25 +0,0 @@ -function HandleClearCommand( Split, Player ) - - if (Split[2] == nil) then - SendMessage( Player, "Usage: /clear " ) - return true - end - - local InventoryCleared = false; - local ClearInventory = function(OtherPlayer) - if (OtherPlayer:GetName() == Split[2]) then - OtherPlayer:GetInventory():Clear() - InventoryCleared = true - end - end - - cRoot:Get():FindAndDoWithPlayer(Split[2], ClearInventory); - if (InventoryCleared) then - SendMessageSuccess( Player, "You cleared the inventory of " .. Split[2] ) - return true - else - SendMessageFailure( Player, "Player not found" ) - return true - end - -end diff --git a/MCServer/Plugins/Core/console.lua b/MCServer/Plugins/Core/console.lua deleted file mode 100644 index 8ae8cb675..000000000 --- a/MCServer/Plugins/Core/console.lua +++ /dev/null @@ -1,405 +0,0 @@ --- Implements things related to console commands - -function InitConsoleCommands() - local PluginMgr = cPluginManager:Get(); - - -- Please keep the list alpha-sorted - PluginMgr:BindConsoleCommand("ban", HandleConsoleBan, " ~ Bans a player by name"); - PluginMgr:BindConsoleCommand("banlist ips", HandleConsoleBanList, " - Lists all players banned by IP"); - PluginMgr:BindConsoleCommand("banlist", HandleConsoleBanList, " - Lists all players banned by name"); - PluginMgr:BindConsoleCommand("getversion", HandleConsoleVersion, " - Gets server version reported to 1.4+ clients"); - PluginMgr:BindConsoleCommand("help", HandleConsoleHelp, " - Lists all commands"); - PluginMgr:BindConsoleCommand("give", HandleConsoleGive, " - Gives items to the specified player.") - PluginMgr:BindConsoleCommand("list", HandleConsoleList, " - Lists all players in a machine-readable format"); - PluginMgr:BindConsoleCommand("listgroups", HandleConsoleListGroups, " - Shows a list of all the groups"); - PluginMgr:BindConsoleCommand("numchunks", HandleConsoleNumChunks, " - Shows number of chunks currently loaded"); - PluginMgr:BindConsoleCommand("players", HandleConsolePlayers, " - Lists all connected players"); - PluginMgr:BindConsoleCommand("rank", HandleConsoleRank, " ~ Add a player to a group"); - PluginMgr:BindConsoleCommand("reload", HandleConsoleReload, " - Reloads all plugins"); - PluginMgr:BindConsoleCommand("save-all", HandleConsoleSaveAll, " - Saves all chunks"); - PluginMgr:BindConsoleCommand("say", HandleConsoleSay, " - Sends a chat message to all players"); - PluginMgr:BindConsoleCommand("setversion", HandleConsoleVersion, " ~ Sets server version reported to 1.4+ clients"); - PluginMgr:BindConsoleCommand("unban", HandleConsoleUnban, " ~ Unbans a player by name"); - PluginMgr:BindConsoleCommand("unload", HandleConsoleUnload, " - Unloads all unused chunks"); -end - - - - - -function HandleConsoleGive(Split) - - -- Make sure there are a correct number of arguments. - if #Split ~= 3 and #Split ~= 4 and #Split ~= 5 then - return true, "Usage: give [amount] [meta]" - end - - -- Get the item from the arguments and check it's valid. - local Item = cItem() - if #Split == 5 then - local FoundItem = StringToItem(Split[3] .. ":" .. Split[5], Item) - else - local FoundItem = StringToItem(Split[3], Item) - end - if not IsValidItem(Item.m_ItemType) then -- StringToItem does not check if item is valid - FoundItem = false - end - - if not FoundItem then - return true, "Invalid item id or name!" - end - - -- Work out how many items the user wants. - local ItemAmount = 1 - if #Split > 3 then - ItemAmount = tonumber(Split[4]) - if ItemAmount == nil or ItemAmount < 1 or ItemAmount > 512 then - return true, "Invalid amount!" - end - end - - Item.m_ItemCount = ItemAmount - - -- Get the playername from the split. - local playerName = Split[2] - - local function giveItems(newPlayer) - local ItemsGiven = newPlayer:GetInventory():AddItem(Item) - if ItemsGiven == ItemAmount then - SendMessageSuccess( newPlayer, "There you go!" ) - LOG("Gave " .. newPlayer:GetName() .. " " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage) - else - SendMessageFailure( Player, "Not enough space in inventory, only gave " .. ItemsGiven) - return true, "Only " .. Item.m_ItemCount .. " out of " .. ItemsGiven .. "items could be delivered." - end - end - - -- Finally give the items to the player. - itemStatus = cRoot:Get():FindAndDoWithPlayer(playerName, giveItems) - - -- Check to make sure that giving items was successful. - if not itemStatus then - return true, "There was no player that matched your query." - end - - return true -end - - - - - -function HandleConsoleBan(Split) - if (#Split < 2) then - return true, "Usage: ban [Player] "; - end - - local Reason = cChatColor.Red .. "You have been banned." .. cChatColor.White .. " Did you do something illegal?" - if( #Split > 2 ) then - Reason = table.concat(Split, " ", 3) - end - - if KickPlayer(Split[2], Reason) == false then - BannedPlayersIni:DeleteValue("Banned", Split[2]) - BannedPlayersIni:SetValueB("Banned", Split[2], true) - BannedPlayersIni:WriteFile() - LOGINFO("Could not find player, but banned anyway" ) - else - BannedPlayersIni:DeleteValue("Banned", Split[2]) - BannedPlayersIni:SetValueB("Banned", Split[2], true) - BannedPlayersIni:WriteFile() - LOGINFO("Successfully kicked and banned player" ) - end - - return true -end - - - - - -function HandleConsoleUnban(Split) - - if #Split < 2 then - return true, "Usage: /unban [Player]" - end - - if( BannedPlayersIni:GetValueB("Banned", Split[2], false) == false ) then - return true, Split[2] .. " is not banned!" - end - - BannedPlayersIni:SetValueB("Banned", Split[2], false, false) - BannedPlayersIni:WriteFile() - - local Server = cRoot:Get():GetServer() - return true, "Unbanned " .. Split[2] -end - - - - - -function HandleConsoleBanList(Split) - if (#Split == 1) then - return true, BanListByName(); - end - - if (string.lower(Split[2]) == "ips") then - return true, BanListByIPs(); - end - - return true, "Unknown banlist subcommand"; -end - - - - - -function HandleConsoleHelp(Split) - local Commands = {}; -- {index => {"Command", "HelpString"} } - local MaxLength = 0; - local AddToTable = function(Command, HelpString) - table.insert(Commands, { Command, HelpString }); - local CmdLen = Command:len(); - if (CmdLen > MaxLength) then - MaxLength = CmdLen; - end - end - - cPluginManager:Get():ForEachConsoleCommand(AddToTable); - - -- Sort the table: - local CompareCommands = function(a, b) - return a[1] < b[1]; -- compare command strings - end - table.sort(Commands, CompareCommands); - - local Out = ""; - Out = "'-' denotes no prefix, '~' denotes that a value is required.\n" - for i, Command in ipairs(Commands) do - Out = Out .. Command[1] .. string.rep(" ", MaxLength - Command[1]:len()); -- Align to a table - Out = Out .. Command[2] .. "\n"; - end - return true, Out; -end - - - - - -function HandleConsoleList(Split) - -- Get a list of all players, one playername per line - local Out = ""; - cRoot:Get():ForEachWorld( - function (a_World) - a_World:ForEachPlayer( - function (a_Player) - Out = Out .. a_Player:GetName() .. "\n"; - end - ); - end - ); - return true, Out; -end - - - - - -function HandleConsoleListGroups(Split) - -- Read the groups.ini file: - local GroupsIni = cIniFile("groups.ini"); - if (not(GroupsIni:ReadFile())) then - return true, "No groups found"; - end - - -- Read the groups: - Number = GroupsIni:NumKeys(); - Groups = {}; - for i = 0, Number do - table.insert(Groups, GroupsIni:KeyName(i)) - end - - -- Output the groups, concatenated to a string: - local Out = "Groups:\n" - Out = Out .. table.concat(Groups, ", "); - return true, Out; -end - - - - - -function HandleConsoleNumChunks(Split) - local Output = {}; - local AddNumChunks = function(World) - Output[World:GetName()] = World:GetNumChunks(); - end; - - cRoot:Get():ForEachWorld(AddNumChunks); - - local Total = 0; - local Out = ""; - for name, num in pairs(Output) do - Out = Out .. " " .. name .. ": " .. num .. " chunks\n"; - Total = Total + num; - end - Out = Out .. "Total: " .. Total .. " chunks\n"; - - return true, Out; -end - - - - - -function HandleConsolePlayers(Split) - local PlayersInWorlds = {}; -- "WorldName" => [players array] - local AddToTable = function(Player) - local WorldName = Player:GetWorld():GetName(); - if (PlayersInWorlds[WorldName] == nil) then - PlayersInWorlds[WorldName] = {}; - end - table.insert(PlayersInWorlds[WorldName], Player:GetName() .. " @ " .. Player:GetIP()); - end - - cRoot:Get():ForEachPlayer(AddToTable); - - local Out = ""; - for WorldName, Players in pairs(PlayersInWorlds) do - Out = Out .. "World " .. WorldName .. ":\n"; - for i, PlayerName in ipairs(Players) do - Out = Out .. " " .. PlayerName .. "\n"; - end - end - - return true, Out; -end - - - - - -function HandleConsoleVersion(Split) - if (#Split == 1) then - -- Display current version: - local Version = cRoot:Get():GetPrimaryServerVersion(); - return true, "Primary server version: #" .. Version .. ", " .. cRoot:GetProtocolVersionTextFromInt(Version); - end - - -- Set new value as the version: - cRoot:Get():SetPrimaryServerVersion(tonumber(Split[2])); - local Version = cRoot:Get():GetPrimaryServerVersion(); - return true, "Primary server version is now #" .. Version .. ", " .. cRoot:GetProtocolVersionTextFromInt(Version); -end - - - - - -function HandleConsoleRank(Split) - if (Split[2] == nil) or (Split[3] == nil) then - return true, "Usage: /rank [Player] [Group]"; - end - local Out = ""; - - -- Read the groups.ini file: - local GroupsIni = cIniFile("groups.ini") - if (not(GroupsIni:ReadFile())) then - Out = "Could not read groups.ini, creating anew!\n" - end - - -- Find the group: - if (GroupsIni:FindKey(Split[3]) == -1) then - return true, Out .. "Group does not exist"; - end - - -- Read the users.ini file: - local UsersIni = cIniFile("users.ini"); - if (not(UsersIni:ReadFile())) then - Out = Out .. "Could not read users.ini, creating anew!\n"; - end - - -- Write the new group value to users.ini: - UsersIni:DeleteKey(Split[2]); - UsersIni:GetValueSet(Split[2], "Groups", Split[3]); - UsersIni:WriteFile(); - - -- Reload the player's permissions: - cRoot:Get():ForEachWorld( - function (World) - World:ForEachPlayer( - function (Player) - if (Player:GetName() == Split[2]) then - SendMessage( Player, "You were moved to group " .. Split[3] ) - Player:LoadPermissionsFromDisk(); - end - end - ); - end - ) - - return true, Out .. "Player " .. Split[2] .. " was moved to " .. Split[3]; -end - - - - - -function HandleConsoleReload(Split) - cRoot:Get():ForEachWorld( - function (a_World) - a_World:BroadcastChat(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Reloading all plugins!"); - end - ) - cPluginManager:Get():ReloadPlugins(); - return true; -end - - - - - -function HandleConsoleSaveAll(Split) - cRoot:Get():ForEachWorld( - function (a_World) - a_World:BroadcastChat(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Saving all chunks!"); - end - ) - cRoot:Get():SaveAllChunks(); - return true; -end - - - - - -function HandleConsoleSay(Split) - table.remove(Split, 1); - local Message = ""; - for i, Text in ipairs(Split) do - Message = Message .. " " .. Text; - end - Message = Message:sub(2); -- Cut off the first space - cRoot:Get():GetServer():BroadcastChat(cChatColor.Gold .. "[SERVER] " .. cChatColor.Yellow .. Message); - return true; -end - - - - - -function HandleConsoleUnload(Split) - local UnloadChunks = function(World) - World:UnloadUnusedChunks(); - end - - local Out = "Num loaded chunks before: " .. cRoot:Get():GetTotalChunkCount() .. "\n"; - cRoot:Get():ForEachWorld(UnloadChunks); - Out = Out .. "Num loaded chunks after: " .. cRoot:Get():GetTotalChunkCount(); - return true, Out; -end - - - - diff --git a/MCServer/Plugins/Core/do.lua b/MCServer/Plugins/Core/do.lua deleted file mode 100644 index 6ac7e96cd..000000000 --- a/MCServer/Plugins/Core/do.lua +++ /dev/null @@ -1,29 +0,0 @@ -function HandleDoCommand( Split, Player ) - - if #Split < 3 then - SendMessage( "Usage: /do [arguments]" ) - return true - end - - -- Get the command and arguments. - local newSplit = table.concat( Split, " ", 3 ) - - local pluginManager = cRoot:Get():GetPluginManager() - pluginManager:ExecuteCommand( Split[2], newSplit ) - -end - -function HandleSudoCommand ( Split, Player ) - - if #Split < 3 then - SendMessage( "Usage: /sudo [arguments]" ) - return true - end - - -- Get the command and arguments. - local newSplit = table.concat( Split, " ", 3 ) - - local pluginManager = cRoot:Get():GetPluginManager() - pluginManager:ForceExecuteCommand( Split[2], newSplit ) - -end diff --git a/MCServer/Plugins/Core/functions.lua b/MCServer/Plugins/Core/functions.lua deleted file mode 100644 index 75a078a53..000000000 --- a/MCServer/Plugins/Core/functions.lua +++ /dev/null @@ -1,162 +0,0 @@ -function SetBackCoordinates( Player ) - BackCoords[Player:GetName()] = Vector3i( Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) -end - -function SendMessage(a_Player, a_Message) - if (g_UsePrefixes) then - a_Player:SendMessage(cChatColor.Yellow .. "[INFO] " .. cChatColor.White .. a_Message) - else - a_Player:SendMessage(cChatColor.Yellow .. a_Message) - end -end - -function SendMessageSuccess(a_Player, a_Message) - if (g_UsePrefixes) then - a_Player:SendMessage(cChatColor.Green .. "[INFO] " .. cChatColor.White .. a_Message) - else - a_Player:SendMessage(cChatColor.Green .. a_Message) - end -end - -function SendMessageFailure(a_Player, a_Message) - if (g_UsePrefixes) then - a_Player:SendMessage(cChatColor.Red .. "[INFO] " .. cChatColor.White .. a_Message) - else - a_Player:SendMessage(cChatColor.Red .. a_Message) - end -end - ---- Returns the list of players banned by name, separated by ", " -function BanListByName() - local NumValues = BannedPlayersIni:NumValues("Banned"); - local Banned = {}; - local KeyID = BannedPlayersIni:FindKey("Banned"); - for i = 1, NumValues do - local PlayerName = BannedPlayersIni:ValueName(KeyID, i - 1); - if (BannedPlayersIni:GetValueB("Banned", PlayerName)) then - -- Player listed AND banned - table.insert(Banned, PlayerName); - end - end - return table.concat(Banned, ", "); -end - ---- Returns the list of players banned by IP, separated by ", " -function BanListByIPs() - -- TODO: No IP ban implemented yet - return ""; -end - ---- Kicks a player by name, with the specified reason; returns bool whether found and player's real name -function KickPlayer( PlayerName, Reason ) - - local RealName = "" - if (Reason == nil) then - Reason = "You have been kicked" - end - - local FoundPlayerCallback = function( a_Player ) - RealName = a_Player:GetName() - - local Server = cRoot:Get():GetServer() - LOGINFO( "'" .. RealName .. "' is being kicked for ( "..Reason..") " ) - Server:SendMessage("Kicking " .. RealName) - - a_Player:GetClientHandle():Kick(Reason) - end - - if not cRoot:Get():FindAndDoWithPlayer( PlayerName, FoundPlayerCallback ) then - -- Could not find player - return false - end - - return true, RealName -- Player has been kicked - -end - - -function ReturnColorFromChar( Split, char ) - - -- Check if the char represents a color. Else return nil. - if char == "0" then - return cChatColor.Black - elseif char == "1" then - return cChatColor.Navy - elseif char == "2" then - return cChatColor.Green - elseif char == "3" then - return cChatColor.Blue - elseif char == "4" then - return cChatColor.Red - elseif char == "5" then - return cChatColor.Purple - elseif char == "6" then - return cChatColor.Gold - elseif char == "7" then - return cChatColor.LightGray - elseif char == "8" then - return cChatColor.Gray - elseif char == "9" then - return cChatColor.DarkPurple - elseif char == "a" then - return cChatColor.LightGreen - elseif char == "b" then - return cChatColor.LightBlue - elseif char == "c" then - return cChatColor.Rose - elseif char == "d" then - return cChatColor.LightPurple - elseif char == "e" then - return cChatColor.Yellow - elseif char == "f" then - return cChatColor.White - elseif char == "k" then - return cChatColor.Random - elseif char == "l" then - return cChatColor.Bold - elseif char == "m" then - return cChatColor.Strikethrough - elseif char == "n" then - return cChatColor.Underlined - elseif char == "o" then - return cChatColor.Italic - elseif char == "r" then - return cChatColor.Plain - end - -end - -function CheckHardcore(Victim) - if HardCore == "true" then - if Victim:IsPlayer() == true then - local KilledPlayer = tolua.cast(Victim, "cPlayer") - BanPlayer(KilledPlayer:GetName(), "You died, haha. Good game, bro.") - end - end -end - --- Teleports a_SrcPlayer to a player named a_DstPlayerName; if a_TellDst is true, will send a notice to the destination player -function TeleportToPlayer( a_SrcPlayer, a_DstPlayerName, a_TellDst ) - - local teleport = function(OtherPlayer) - - if OtherPlayer == a_SrcPlayer then - -- Asked to teleport to self? - SendMessageFailure( a_SrcPlayer, "Y' can't teleport to yerself!" ) - else - SetBackCoordinates( a_SrcPlayer ) - a_SrcPlayer:TeleportToEntity( OtherPlayer ) - SendMessageSuccess( a_SrcPlayer, "You teleported to " .. OtherPlayer:GetName() .. "!" ) - if (a_TellDst) then - SendMessage( OtherPlayer, Player:GetName().." teleported to you!" ) - end - end - - end - - local World = a_SrcPlayer:GetWorld() - if not World:DoWithPlayer(a_DstPlayerName, teleport) then - SendMessageFailure( a_SrcPlayer, "Can't find player " .. a_DstPlayerName) - end - -end diff --git a/MCServer/Plugins/Core/give.lua b/MCServer/Plugins/Core/give.lua deleted file mode 100644 index 04f01614d..000000000 --- a/MCServer/Plugins/Core/give.lua +++ /dev/null @@ -1,66 +0,0 @@ -function HandleGiveCommand(Split, Player) - - -- Make sure there are a correct number of arguments. - if #Split ~= 3 and #Split ~= 4 and #Split ~= 5 then - SendMessage( Player, "Usage: /give [amount] [meta]" ) - return true - end - - -- Get the item from the arguments and check it's valid. - local Item = cItem() - if #Split == 5 then - local FoundItem = StringToItem( Split[3] .. ":" .. Split[5], Item ) - else - local FoundItem = StringToItem( Split[3], Item ) - end - - if not IsValidItem( Item.m_ItemType ) then -- StringToItem does not check if item is valid - FoundItem = false - end - - if not FoundItem then - SendMessageFailure( Player, "Invalid item id or name!" ) - return true - end - - -- Work out how many items the user wants. - local ItemAmount = 1 - if #Split > 3 then - ItemAmount = tonumber( Split[4] ) - if ItemAmount == nil or ItemAmount < 1 or ItemAmount > 512 then - SendMessageFailure( Player, "Invalid amount!" ) - return true - end - end - - Item.m_ItemCount = ItemAmount - - -- Get the playername from the split. - local playerName = Split[2] - - local function giveItems( newPlayer ) - local ItemsGiven = newPlayer:GetInventory():AddItem( Item ) - if ItemsGiven == ItemAmount then - SendMessageSuccess( newPlayer, "You were given " .. Item.m_ItemCount .. " of " .. Item.m_ItemType .. "." ) - if not newPlayer == Player then - SendMessageSuccess( Player, "Items given!" ) - end - LOG("Gave " .. newPlayer:GetName() .. " " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage ) - else - SendMessageFailure( Player, "Not enough space in inventory, only gave " .. ItemsGiven ) - LOG( "Player " .. Player:GetName() .. " asked for " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage ..", but only could fit " .. ItemsGiven ) - end - return true - end - - -- Finally give the items to the player. - itemStatus = cRoot:Get():FindAndDoWithPlayer( playerName, giveItems ) - - -- Check to make sure that giving items was successful. - if not itemStatus then - SendMessageFailure( Player, "There was no player that matched your query." ) - end - - return true - -end diff --git a/MCServer/Plugins/Core/gm.lua b/MCServer/Plugins/Core/gm.lua deleted file mode 100644 index 8e6a1a12f..000000000 --- a/MCServer/Plugins/Core/gm.lua +++ /dev/null @@ -1,11 +0,0 @@ -function HandleChangeGMCommand( Split, Player ) - - if( #Split ~= 2 ) then - SendMessage( Player, "Usage: /gm [0|1]" ) - return true - end - - Player:SetGameMode( Split[2] ) - return true - -end diff --git a/MCServer/Plugins/Core/help.lua b/MCServer/Plugins/Core/help.lua deleted file mode 100644 index fe8c50492..000000000 --- a/MCServer/Plugins/Core/help.lua +++ /dev/null @@ -1,43 +0,0 @@ -function HandleHelpCommand( Split, Player ) - - local PluginManager = cRoot:Get():GetPluginManager() - - local LinesPerPage = 8 - local CurrentPage = 1 - local CurrentLine = 0 - local PageRequested = 1 - local Output = {} - - if (#Split == 2) then - PageRequested = tonumber( Split[2] ) - end - - local Process = function( Command, Permission, HelpString ) - if not (Player:HasPermission(Permission)) then - return false - end - if (HelpString == "") then - return false - end - - CurrentLine = CurrentLine + 1 - CurrentPage = math.floor( CurrentLine / LinesPerPage ) + 1 - if (CurrentPage ~= PageRequested) then - return false - end - table.insert( Output, Command .. HelpString ) - end - - PluginManager:ForEachCommand( Process ) - - -- CurrentPage now contains the total number of pages, and Output has the individual help lines to be sent - - SendMessage( Player, "Page " .. PageRequested .. " out of " .. CurrentPage .. "." ) - SendMessage( Player, "'-' means no prefix, '~' means a value is required." ) - for idx, msg in ipairs( Output ) do - SendMessage( Player, msg ) - end - - return true - -end diff --git a/MCServer/Plugins/Core/item.lua b/MCServer/Plugins/Core/item.lua deleted file mode 100644 index 069291122..000000000 --- a/MCServer/Plugins/Core/item.lua +++ /dev/null @@ -1,26 +0,0 @@ -function HandleItemCommand( Split, Player ) - - if ((#Split ~= 2) and (#Split ~=3)) then - SendMessage( Player, "Usage: /i [:meta] [amount]" ) - return true - end - - local itemSplit = StringSplit(Split[2], ":") - local newSplit = {} - - newSplit[1] = "/give" - newSplit[2] = Player:GetName() - newSplit[3] = itemSplit[1] - if Split[3] ~= nil then - newSplit[4] = Split[3] - else - newSplit[4] = 1 - end - if itemSplit[2] ~= nil then - newSplit[5] = itemSplit[2] - end - - HandleGiveCommand( newSplit, Player ) - return true - -end diff --git a/MCServer/Plugins/Core/itemrepair.lua b/MCServer/Plugins/Core/itemrepair.lua deleted file mode 100644 index ee411dcc2..000000000 --- a/MCServer/Plugins/Core/itemrepair.lua +++ /dev/null @@ -1,202 +0,0 @@ --- Based on Fixies plugin v2 by Taugeshtu --- how much "extra" points are healed per a repair operation (fraction of full health) -BONUS = 0.1 - -function OnCraftingNoRecipe(Player, Grid, Recipe) - local _do_fix = false - local Items = {} - for x = 0, Grid:GetWidth() - 1 do - for y = 0, Grid:GetHeight() - 1 do - local Item = Grid:GetItem(x, y) - if (Item.m_ItemType ~= E_ITEM_EMPTY) then - table.insert(Items, Item) - end - end - end - - if (#Items ~= 2) then - -- Only two items together can be fixed - return false - end - - if (Items[1].m_ItemType ~= Items[2].m_ItemType) then - -- Only items of the same type may be fixed - return false - end - - if ( - (Items[1].m_ItemDamage == 0) or - (Items[2].m_ItemDamage == 0) - ) - then - -- Only damaged items may be fixed - return false - end - - local _ID = Items[1].m_ItemType - local _least_hp = math.max(Items[1].m_ItemDamage, Items[2].m_ItemDamage) - local _most_hp = math.min(Items[1].m_ItemDamage, Items[2].m_ItemDamage) - local _item_hp = 0 - - -- TODO: This could be refactored into better code, using an _ID-indexed table for _item_hp - - if ( - (_ID == E_ITEM_WOODEN_SHOVEL) or - (_ID == E_ITEM_WOODEN_AXE) or - (_ID == E_ITEM_WOODEN_PICKAXE) or - (_ID == E_ITEM_WOODEN_SWORD) or - (_ID == E_ITEM_WOODEN_HOE) - ) - then - _item_hp = 60 - _do_fix = true - end - - if ( - (_ID == E_ITEM_STONE_SHOVEL) or - (_ID == E_ITEM_STONE_AXE) or - (_ID == E_ITEM_STONE_PICKAXE) or - (_ID == E_ITEM_STONE_SWORD) or - (_ID == E_ITEM_STONE_HOE) - ) - then - _item_hp = 132 - _do_fix = true - end - - if ( - (_ID == E_ITEM_IRON_SHOVEL) or - (_ID == E_ITEM_IRON_AXE) or - (_ID == E_ITEM_IRON_PICKAXE) or - (_ID == E_ITEM_IRON_SWORD) or - (_ID == E_ITEM_IRON_HOE) - ) - then - _item_hp = 251 - _do_fix = true - end - - if ( - (_ID == E_ITEM_GOLD_SHOVEL) or - (_ID == E_ITEM_GOLD_AXE) or - (_ID == E_ITEM_GOLD_PICKAXE) or - (_ID == E_ITEM_GOLD_SWORD) or - (_ID == E_ITEM_GOLD_HOE) - ) - then - _item_hp = 33 - _do_fix = true - end - - if ( - (_ID == E_ITEM_DIAMOND_SHOVEL) or - (_ID == E_ITEM_DIAMOND_AXE) or - (_ID == E_ITEM_DIAMOND_PICKAXE) or - (_ID == E_ITEM_DIAMOND_SWORD) or - (_ID == E_ITEM_DIAMOND_HOE) - ) - then - _item_hp = 1562 - _do_fix = true - end - - if (_ID == E_ITEM_LEATHER_CAP) then - _item_hp = 56 - _do_fix = true - end - if (_ID == E_ITEM_LEATHER_TUNIC) then - _item_hp = 82 - _do_fix = true - end - if (_ID == E_ITEM_LEATHER_PANTS) then - _item_hp = 76 - _do_fix = true - end - if (_ID == E_ITEM_LEATHER_BOOTS) then - _item_hp = 66 - _do_fix = true - end - - - if (_ID == E_ITEM_CHAIN_HELMET) then - _item_hp = 78 - _do_fix = true - end - if (_ID == E_ITEM_CHAIN_CHESTPLATE) then - _item_hp = 114 - _do_fix = true - end - if (_ID == E_ITEM_CHAIN_LEGGINGS) then - _item_hp = 106 - _do_fix = true - end - if (_ID == E_ITEM_CHAIN_BOOTS) then - _item_hp = 92 - _do_fix = true - end - - - if (_ID == E_ITEM_IRON_HELMET) then - _item_hp = 166 - _do_fix = true - end - if (_ID == E_ITEM_IRON_CHESTPLATE) then - _item_hp = 242 - _do_fix = true - end - if (_ID == E_ITEM_IRON_LEGGINGS) then - _item_hp = 226 - _do_fix = true - end - if (_ID == E_ITEM_IRON_BOOTS) then - _item_hp = 196 - _do_fix = true - end - - - if (_ID == E_ITEM_GOLD_HELMET) then - _item_hp = 78 - _do_fix = true - end - if (_ID == E_ITEM_GOLD_CHESTPLATE) then - _item_hp = 114 - _do_fix = true - end - if (_ID == E_ITEM_GOLD_LEGGINGS) then - _item_hp = 106 - _do_fix = true - end - if (_ID == E_ITEM_GOLD_BOOTS) then - _item_hp = 92 - _do_fix = true - end - - - if (_ID == E_ITEM_DIAMOND_HELMET) then - _item_hp = 364 - _do_fix = true - end - if (_ID == E_ITEM_DIAMOND_CHESTPLATE)then - _item_hp = 529 - _do_fix = true - end - if (_ID == E_ITEM_DIAMOND_LEGGINGS) then - _item_hp = 496 - _do_fix = true - end - if (_ID == E_ITEM_DIAMOND_BOOTS) then - _item_hp = 430 - _do_fix = true - end - -- ///////////////////////////////////////////////////// - - if (_do_fix == true) then - local _hp = _most_hp - (_item_hp - _least_hp) - _item_hp * BONUS - _hp = math.max(_hp, 0) - Recipe:SetResult(_ID, 1, _hp) - Recipe:SetIngredient(Items[1].x, Items[1].y, Items[1]); - Recipe:SetIngredient(Items[2].x, Items[2].y, Items[2]); - return true - end - return false -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/kick.lua b/MCServer/Plugins/Core/kick.lua deleted file mode 100644 index 1bc2ab128..000000000 --- a/MCServer/Plugins/Core/kick.lua +++ /dev/null @@ -1,19 +0,0 @@ -function HandleKickCommand( Split, Player ) - - if( #Split < 2 ) then - SendMessage( Player, "Usage: /kick [Player] " ) - return true - end - - local Reason = "You have been kicked" - if ( #Split > 2 ) then - Reason = table.concat( Split, " ", 3 ) - end - - if( KickPlayer( Split[2], Reason ) == false ) then - SendMessageFailure( Player, "Could not find player " .. Split[2] ) - end - - return true - -end diff --git a/MCServer/Plugins/Core/kill.lua b/MCServer/Plugins/Core/kill.lua deleted file mode 100644 index d36c9d271..000000000 --- a/MCServer/Plugins/Core/kill.lua +++ /dev/null @@ -1,34 +0,0 @@ -function HandleKillCommand( Split, Player ) - - if (Split[2] == nil) then - Player:TakeDamage(dtInVoid, nil, 1000, 1000, 0) - return true - end - - local HasKilled = false; - local KillPlayer = function(OtherPlayer) - if (OtherPlayer:GetName() == Split[2]) then - if (OtherPlayer:GetGameMode() == 1) then - HasKilled = creative - end - if (OtherPlayer:GetGameMode() == 0) then - OtherPlayer:TakeDamage(dtInVoid, nil, 1000, 1000, 0) - HasKilled = true - end - end - end - - cRoot:Get():FindAndDoWithPlayer(Split[2], KillPlayer); - if (HasKilled == creative) then - SendMessageFailure( Player, "Player " .. Split[2] .. " is in creative mode" ) - return true - end - if (HasKilled) then - SendMessageSuccess( Player, "Player " .. Split[2] .. " is killed" ) - return true - else - SendMessageFailure( Player, "Player not found" ) - return true - end - -end diff --git a/MCServer/Plugins/Core/locate.lua b/MCServer/Plugins/Core/locate.lua deleted file mode 100644 index f5df698c9..000000000 --- a/MCServer/Plugins/Core/locate.lua +++ /dev/null @@ -1,4 +0,0 @@ -function HandleLocateCommand( Split, Player ) - SendMessage( Player, string.format("You are at [X:%0.2f Y:%0.2f Z:%0.2f] in world %s", Player:GetPosX(), Player:GetPosY(), Player:GetPosZ(), Player:GetWorld():GetName()) ) - return true -end diff --git a/MCServer/Plugins/Core/main.lua b/MCServer/Plugins/Core/main.lua deleted file mode 100644 index 28df69cc3..000000000 --- a/MCServer/Plugins/Core/main.lua +++ /dev/null @@ -1,198 +0,0 @@ ---COMMENCE VARIABLES -PLUGIN = {} -BannedPlayersIni = {} -WhiteListIni = {} -BackCoords = {} -Messages = {} -Destination = {} ---END VARIABLES - --- Configuration --- Use prefixes or not. --- If set to true, messages are prefixed, e. g. "[FATAL]". If false, messages are colored. -g_UsePrefixes = true - ---COMMENCE AWESOMENESS! -function Initialize( Plugin ) - PLUGIN = Plugin - - Plugin:SetName( "Core" ) - Plugin:SetVersion( 13 ) - - --ADD HOOKS - PluginManager = cRoot:Get():GetPluginManager() - PluginManager:AddHook( Plugin, cPluginManager.HOOK_PLAYER_JOINED ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_DISCONNECT ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_PLAYER_BREAKING_BLOCK ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_PLAYER_PLACING_BLOCK ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_LOGIN ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_KILLING ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE ) - PluginManager:AddHook( Plugin, cPluginManager.HOOK_CHAT ) -- used in web_chat.lua - PluginManager:AddHook( Plugin, cPluginManager.HOOK_PLAYER_MOVING ) - - --PLEASE ALPHA SORT http://elmosaukko.com/sort-alphabetically/ THIS LIST - --BIND COMMANDS - PluginManager:BindCommand("/back", "core.back", HandleBackCommand, " - Return to your last position") - PluginManager:BindCommand("/ban", "core.ban", HandleBanCommand, " ~ Ban a player") - PluginManager:BindCommand("/clear", "core.clear", HandleClearCommand, " - Clear the inventory of some player") - PluginManager:BindCommand("/give", "core.give", HandleGiveCommand, " ~ Give someone an item") - PluginManager:BindCommand("/gm", "core.changegm", HandleChangeGMCommand, " ~ Change your gamemode") - PluginManager:BindCommand("/groups", "core.groups", HandleGroupsCommand, " - Shows a list of all the groups") - PluginManager:BindCommand("/help", "core.help", HandleHelpCommand, " ~ Show available commands") - PluginManager:BindCommand("/i", "core.give", HandleItemCommand, "") - PluginManager:BindCommand("/item", "core.give", HandleItemCommand, " - Give yourself an item.") - PluginManager:BindCommand("/kick", "core.kick", HandleKickCommand, " ~ Kick a player") - PluginManager:BindCommand("/kill", "core.kill", HandleKillCommand, " - Kill some player") - PluginManager:BindCommand("/locate", "core.locate", HandleLocateCommand, " - Show your current server coordinates") - PluginManager:BindCommand("/me", "core.me", HandleMeCommand, " ~ Tell what you are doing") - PluginManager:BindCommand("/motd", "core.motd", HandleMOTDCommand, " - Show message of the day") - PluginManager:BindCommand("/msg", "core.tell", HandleTellCommand, "") - PluginManager:BindCommand("/plugins", "core.plugins", HandlePluginsCommand, " - Show list of plugins") - PluginManager:BindCommand("/portal", "core.portal", HandlePortalCommand, " ~ Move to a different world") - PluginManager:BindCommand("/rank", "core.rank", HandleRankCommand, " ~ Add someone to a group") - PluginManager:BindCommand("/regen", "core.regen", HandleRegenCommand, " ~ Regenerates a chunk, current or specified") - PluginManager:BindCommand("/reload", "core.reload", HandleReloadCommand, " - Reload all plugins") - PluginManager:BindCommand("/save-all", "core.save-all", HandleSaveAllCommand, " - Saves all your worlds") - PluginManager:BindCommand("/spawn", "core.spawn", HandleSpawnCommand, " - Return to the spawn") - PluginManager:BindCommand("/stop", "core.stop", HandleStopCommand, " - Stops the server") - PluginManager:BindCommand("/tell", "core.tell", HandleTellCommand, " ~ Send a private message") - PluginManager:BindCommand("/time", "core.time", HandleTimeCommand, " ~ Sets the time of day") - PluginManager:BindCommand("/toggledownfall", "core.toggledownfall", HandleDownfallCommand, " - Toggles the weather") - PluginManager:BindCommand("/top", "core.top", HandleTopCommand, " - Teleport yourself to the top most block") - PluginManager:BindCommand("/tp", "core.teleport", HandleTPCommand, " ~ Teleport yourself to a player") - PluginManager:BindCommand("/tpa", "core.teleport", HandleTPACommand, " ~ Ask to teleport yourself to a player") - PluginManager:BindCommand("/tpaccept", "core.teleport", HandleTPAcceptCommand, " ~ Accept a teleportation request") - PluginManager:BindCommand("/unban", "core.unban", HandleUnbanCommand, " ~ Unban a player") - PluginManager:BindCommand("/viewdistance", "core.viewdistance", HandleViewDistanceCommand, " [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."] - Change your view distance") - PluginManager:BindCommand("/weather", "core.weather", HandleWeatherCommand, " ~ Change world weather") - PluginManager:BindCommand("/worlds", "core.worlds", HandleWorldsCommand, " - Shows a list of all the worlds") - PluginManager:BindCommand("/sudo", "core.sudo", HandleSudoCommand, " - Runs a command as a player, ignoring permissions") - PluginManager:BindCommand("/do", "core.do", HandleDoCommand, " - Runs a command as a player.") - - InitConsoleCommands() - - --LOAD SETTINGS - IniFile = cIniFile( "settings.ini" ) - if IniFile:ReadFile() == true then - HardCore = IniFile:GetValueSet( "GameMode", "Hardcore", "false" ) - IniFile:WriteFile() - end - - WorldsSpawnProtect = {} - local KeyIdx = IniFile:FindKey( "Worlds" ) --(FIND WHERE 'WORLDS' KEY IS LOCATED) - local NumValues = IniFile:GetNumValues( KeyIdx ) --(HOW MANY VALUES ARE THERE?) - for i = 0, NumValues - 1 do --(FOR EVERY WORLD KEY, TAKING ACCOUNT OF OFF BY ONE ERRORS) - WorldIni = cIniFile( IniFile:GetValue(KeyIdx, i) .. "/world.ini" ) - if WorldIni:ReadFile() == true then - WorldsSpawnProtect[IniFile:GetValue(KeyIdx, i)] = WorldIni:GetValueSetI( "SpawnProtect", "ProtectRadius", 10 ) - WorldIni:WriteFile() - end - end - WorldsWorldLimit = {} - local KeyIdx = IniFile:FindKey( "Worlds" ) --(FIND WHERE 'WORLDS' KEY IS LOCATED) - local NumValues = IniFile:GetNumValues( KeyIdx ) --(HOW MANY VALUES ARE THERE?) - for i = 0, NumValues - 1 do --(FOR EVERY WORLD KEY, TAKING ACCOUNT OF OFF BY ONE ERRORS) - WorldIni = cIniFile( IniFile:GetValue(KeyIdx, i) .. "/world.ini" ) - if WorldIni:ReadFile() == true then - WorldsWorldLimit[IniFile:GetValue(KeyIdx, i)] = WorldIni:GetValueSetI( "WorldLimit", "LimitRadius", 0 ) - WorldIni:WriteFile() - end - end - - --LOAD WHITELIST - WhiteListIni = cIniFile( Plugin:GetLocalDirectory() .. "/whitelist.ini" ) - if WhiteListIni:ReadFile() == true then - if WhiteListIni:GetValueB( "WhiteListSettings", "WhiteListOn", false ) == true then - if WhiteListIni:GetNumValues( "WhiteList" ) > 0 then - LOGINFO( "Core: loaded " .. WhiteListIni:GetNumValues('WhiteList') .. " whitelisted players." ) - else - LOGWARN( "WARNING: WhiteList is on, but there are no people in the whitelist!" ) - end - end - else - WhiteListIni:SetValueB( "WhiteListSettings", "WhiteListOn", false ) - WhiteListIni:SetValue( "WhiteList", "", "" ) -- So it adds an empty header - WhiteListIni:DeleteValue( "WhiteList", "" ) -- And remove the value - WhiteListIni:KeyComment( "WhiteList", "PlayerName=1" ) - if WhiteListIni:WriteFile() == false then - LOGWARN( "WARNING: Could not write to whitelist.ini" ) - end - end - - --LOAD BANNED (BAD LUCK, BRO) - BannedPlayersIni = cIniFile( Plugin:GetLocalDirectory() .. "/banned.ini" ) - if BannedPlayersIni:ReadFile() == true then - if BannedPlayersIni:GetNumValues( "Banned" ) > 0 then - LOGINFO( "Core: loaded " .. BannedPlayersIni:GetNumValues("Banned") .. " banned players." ) - end - else - BannedPlayersIni:SetValue( "Banned", "", "" ) -- So it adds an empty header - BannedPlayersIni:DeleteValue( "Banned", "" ) -- And remove the value - BannedPlayersIni:KeyComment( "Banned", "PlayerName=1" ) - if BannedPlayersIni:WriteFile() == false then - LOGWARN( "WARNING: Could not write to banned.ini" ) - end - end - - --ADD WEB INTERFACE TABULATES - Plugin:AddWebTab( "Manage Server", HandleRequest_ManageServer ) - Plugin:AddWebTab( "Server Settings", HandleRequest_ServerSettings ) - Plugin:AddWebTab( "Chat", HandleRequest_Chat ) - Plugin:AddWebTab( "Playerlist", HandleRequest_PlayerList ) - Plugin:AddWebTab( "Whitelist", HandleRequest_WhiteList ) - Plugin:AddWebTab( "Permissions", HandleRequest_Permissions ) - Plugin:AddWebTab( "Manage Plugins", HandleRequest_ManagePlugins ) - - LoadMotd() - LOG( "Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() ) - - return true - -end ---AWESOMENESS STILL GOING! - ---BEGIN SPAWNPROTECT LOGFILE CODE (COURTSEY OF BEARBIN) -function WriteLog( breakPlace, X, Y, Z, player, id, meta ) - - local logText = {} - - table.insert( logText, player ) - table.insert( logText, " tried to " ) - - if breakPlace == 0 then - table.insert( logText, "break " ) - else - table.insert( logText, "place " ) - end - - - table.insert( logText, ItemToString(cItem(id, 1, meta)) ) - table.insert( logText, " at ") - table.insert( logText, tostring(X) ) - table.insert( logText, ", ") - table.insert( logText, tostring(Y) ) - table.insert( logText, ", ") - table.insert( logText, tostring(Z) ) - table.insert( logText, "." ) - - LOGINFO( table.concat( logText, '') ) - - if LOGTOFILE then - local logFile = io.open( Plugin:GetLocalDirectory() .. '/blocks.log', 'a' ) - logFile:write( table.concat( logText, '' ) .. "\n" ) - logFile:close() - end - - return -end - -function WarnPlayer( Player ) - SendMessageFailure( Player, "Go further from spawn to build" ) - return true -end - -function OnDisable() - LOG( "Disabled Core!" ) -end ---END AWESOMENESS :'( diff --git a/MCServer/Plugins/Core/me.lua b/MCServer/Plugins/Core/me.lua deleted file mode 100644 index 73fb60f73..000000000 --- a/MCServer/Plugins/Core/me.lua +++ /dev/null @@ -1,20 +0,0 @@ -function HandleMeCommand( Split, Player ) - - table.remove( Split, 1 ) - local Message = "" - - for i, Text in ipairs( Split ) do - Message = Message .. " " .. Text - end - - if Split[1] == nil then - SendMessage( Player, "Usage: /me " ) - return true - end - - if Split[1] ~= nil then - cRoot:Get():GetServer():BroadcastChat( Player:GetName() .. "" .. Message ) - return true - end - -end diff --git a/MCServer/Plugins/Core/motd.lua b/MCServer/Plugins/Core/motd.lua deleted file mode 100644 index 3909c18e3..000000000 --- a/MCServer/Plugins/Core/motd.lua +++ /dev/null @@ -1,44 +0,0 @@ -function HandleMOTDCommand( Split, Player ) - ShowMOTDTo( Player ) - return true -end - -function LoadMotd() - - local File = io.open( "motd.txt", "r" ) - - -- Check if the file 'motd.txt' exists, else create it. - if not File then - CreateFile = io.open( "motd.txt", "w" ) - CreateFile:write("@6Welcome to the MCServer test server!\n@6http://www.mc-server.org/\n@6Type /help for all commands") - CreateFile:close() - else - File:close() - end - - for line in io.lines( "motd.txt" ) do - local TempMessage = line - -- Do a for loop that goes to each char in the line. - for I=1, string.len( TempMessage ) do - -- If the char is a '@' then check if the next char represents a color. - if string.sub( TempMessage, I, I ) == "@" then - local Char = string.sub( TempMessage, I + 1, I + 1 ) - local Color = ReturnColorFromChar( TempMessage, Char ) - -- If the next char represented a color then put the color in the string. - if Color ~= nil then - TempMessage = string.gsub( TempMessage, "@" .. Char, Color ) - end - end - end - -- Add the message to the list of messages. - Messages[#Messages + 1] = TempMessage - end - -end - -function ShowMOTDTo( Player ) - for I=1, #Messages do - Player:SendMessage(Messages[I]) - end -end - diff --git a/MCServer/Plugins/Core/onbreakplaceblock.lua b/MCServer/Plugins/Core/onbreakplaceblock.lua deleted file mode 100644 index 5eddc1511..000000000 --- a/MCServer/Plugins/Core/onbreakplaceblock.lua +++ /dev/null @@ -1,119 +0,0 @@ -function OnPlayerPlacingBlock(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ, BlockType) - -- Direction is air check - if (BlockFace == -1) then - return false - end - - local PROTECTRADIUS = WorldsSpawnProtect[Player:GetWorld():GetName()]; - - if not (Player:HasPermission("core.build")) then - return true - else - if not (Player:HasPermission("core.spawnprotect.bypass")) and not (PROTECTRADIUS == 0) then - local World = Player:GetWorld() - local xcoord = World:GetSpawnX() - local ycoord = World:GetSpawnY() - local zcoord = World:GetSpawnZ() - - if not ((BlockX <= (xcoord + PROTECTRADIUS)) and (BlockX >= (xcoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - if not ((BlockY <= (ycoord + PROTECTRADIUS)) and (BlockY >= (ycoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - if not ((BlockZ <= (zcoord + PROTECTRADIUS)) and (BlockZ >= (zcoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - - --WriteLog(1, BlockX, BlockY, BlockZ, Player:GetName(), id, meta) - - WarnPlayer(Player) - - return true - else - if BlockType == "50" or BlockType == "76" then - local X = BlockX - local Y = BlockY - local Z = BlockZ - X, Y, Z = AddFaceDirection(X, Y, Z, BlockFace) - if (Y >= 256 or Y < 0) then - return true - end - - local CheckCollision = function(Player) - -- drop the decimals, we only care about the full block X,Y,Z - local PlayerX = math.floor(Player:GetPosX(), 0) - local PlayerY = math.floor(Player:GetPosY(), 0) - local PlayerZ = math.floor(Player:GetPosZ(), 0) - - local collision = false - if ((BlockFace == BLOCK_FACE_TOP) and (PlayerY == BlockY - 2) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then - collision = true - end - - if ((BlockFace == BLOCK_FACE_BOTTOM) and (PlayerY == BlockY + 1) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then - collision = true - end - - if ((BlockFace == BLOCK_FACE_NORTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ - 1)) then - if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end - end - - if ((BlockFace == BLOCK_FACE_SOUTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ + 1)) then - if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end - end - - if ((BlockFace == BLOCK_FACE_WEST) and (PlayerX == BlockX - 1) and (PlayerZ == BlockZ)) then - if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end - end - - if ((BlockFace == BLOCK_FACE_EAST) and (PlayerX == BlockX + 1) and (PlayerZ == BlockZ)) then - if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end - end - return collision - end - if (Player:GetWorld():ForEachPlayer(CheckCollision) == false) then - return true - end - end - end - end - return false -end - -function OnPlayerBreakingBlock(Player, BlockX, BlockY, BlockZ, BlockFace, Status, OldBlockType, OldBlockMeta) - -- dont check if the direction is in the air - if (BlockFace ~= -1) then - - local PROTECTRADIUS = WorldsSpawnProtect[Player:GetWorld():GetName()]; - - if not (Player:HasPermission("core.build")) then - return true - else - if not (Player:HasPermission("core.spawnprotect.bypass")) and not (PROTECTRADIUS == 0) then - local World = Player:GetWorld() - local xcoord = World:GetSpawnX() - local ycoord = World:GetSpawnY() - local zcoord = World:GetSpawnZ() - - if not ((BlockX <= (xcoord + PROTECTRADIUS)) and (BlockX >= (xcoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - if not ((BlockY <= (ycoord + PROTECTRADIUS)) and (BlockY >= (ycoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - if not ((BlockZ <= (zcoord + PROTECTRADIUS)) and (BlockZ >= (zcoord - PROTECTRADIUS))) then - return false -- Not in spawn area. - end - - --WriteLog(0, BlockX, BlockY, BlockZ, Player:GetName(), id, meta) - - WarnPlayer(Player) - - return true - end - end - end - - return false -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/ondeath.lua b/MCServer/Plugins/Core/ondeath.lua deleted file mode 100644 index 4cb62f6a8..000000000 --- a/MCServer/Plugins/Core/ondeath.lua +++ /dev/null @@ -1,56 +0,0 @@ -function OnKilling(Victim, Killer) - if Victim:IsPlayer() then - SetBackCoordinates( Victim ) - Server = cRoot:Get():GetServer() - if Killer == nil then - if Victim:GetWorld():GetBlock(Victim:GetPosX(), Victim:GetPosY(), Victim:GetPosZ()) == 10 or Victim:GetWorld():GetBlock(Victim:GetPosX(), Victim:GetPosY(), Victim:GetPosZ()) == 11 then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " tried to swim in lava (and failed)" ) - CheckHardcore(Victim) - return false - end - if Victim:IsOnFire() then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was burnt to a cinder" ) - CheckHardcore(Victim) - return false - end - else - if Killer:IsPlayer() then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was terminated by " .. Killer:GetName() ) - CheckHardcore(Victim) - return false - elseif Killer:IsMob() then - if Killer:IsA("cZombie") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was eaten by a zombie") - elseif Killer:IsA("cSkeleton") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was shot by a skeleton" ) - elseif Killer:IsA("cCreeper") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was blown up by a creeper") - elseif Killer:IsA("cSpider") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was ripped apart by a giant spider") - elseif Killer:IsA("cCaveSpider") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was poisoned by a giant cave spider") - elseif Killer:IsA("cBlaze") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was flamed by a blaze") - elseif Killer:IsA("cEnderman") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was " .. cChatColor.Random .. " by an enderman") - elseif Killer:IsA("cSilverfish") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " encountered an unexpectedly fatal silverfish attack") - elseif Killer:IsA("cSlime") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was absorbed and digested by a slime") - elseif Killer:IsA("cWitch") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was enchanted (to death) by a witch") - elseif Killer:IsA("cZombiepigman") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was slain by a zombie pigman") - elseif Killer:IsA("cMagmacube") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was incinerated by a magmacube") - elseif Killer:IsA("cWolf") then - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " was savaged by a wolf") - end - CheckHardcore(Victim) - return false - end - end - Server:SendMessage( cChatColor.Red .. "[FATALITY] " .. cChatColor.White .. Victim:GetName() .. " died of mysterious circumstances") - CheckHardcore(Victim) - end -end diff --git a/MCServer/Plugins/Core/onjoinleave.lua b/MCServer/Plugins/Core/onjoinleave.lua deleted file mode 100644 index cd0ead4fc..000000000 --- a/MCServer/Plugins/Core/onjoinleave.lua +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -function OnPlayerJoined(Player) - ShowMOTDTo(Player) - Player:GetWorld():BroadcastChat(cChatColor.Yellow .. "[JOIN] " .. cChatColor.White .. Player:GetName() .. " has joined the game") - return false -end - - - - - -function OnDisconnect(Player, Reason) - Player:GetWorld():BroadcastChat(cChatColor.Yellow .. "[LEAVE] " .. cChatColor.White .. Player:GetName() .. " has left the game") - return true -end - - - - diff --git a/MCServer/Plugins/Core/onlogin.lua b/MCServer/Plugins/Core/onlogin.lua deleted file mode 100644 index 6826305b2..000000000 --- a/MCServer/Plugins/Core/onlogin.lua +++ /dev/null @@ -1,17 +0,0 @@ -function OnLogin(Client, ProtocolVersion, Username) - if( Username ~= "" ) then - if( BannedPlayersIni:GetValueB("Banned", Username, false) == true ) then - LOGINFO( Username .. " tried to join, but is banned!") - return true -- Player is banned, return true to deny access - end - if( WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false ) == true ) then - if( WhiteListIni:GetValueB("WhiteList", Username, false ) == false ) then -- not on whitelist - local Server = cRoot:Get():GetServer() - Server:SendMessage( Username .. " tried to join, but is not on the whitelist." ) - LOGINFO( Username .. " tried to join, but is not on the whitelist." ) - return true -- Deny access to the server - end - end - end - return false -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/plugins.lua b/MCServer/Plugins/Core/plugins.lua deleted file mode 100644 index 352c80bb3..000000000 --- a/MCServer/Plugins/Core/plugins.lua +++ /dev/null @@ -1,17 +0,0 @@ -function HandlePluginsCommand( Split, Player ) - - local PluginManager = cRoot:Get():GetPluginManager() - local PluginList = PluginManager:GetAllPlugins() - - local PluginTable = {} - for k, Plugin in pairs( PluginList ) do - if Plugin then - table.insert( PluginTable, Plugin:GetName() ) - end - end - - SendMessage( Player, "There are " .. #PluginTable .. " loaded plugins" ) - SendMessage( Player, table.concat( PluginTable , " " ) ) - return true - -end diff --git a/MCServer/Plugins/Core/portal-worlds.lua b/MCServer/Plugins/Core/portal-worlds.lua deleted file mode 100644 index 1112cbc8a..000000000 --- a/MCServer/Plugins/Core/portal-worlds.lua +++ /dev/null @@ -1,41 +0,0 @@ -function HandlePortalCommand( Split, Player ) - - if( #Split ~= 2 ) then - SendMessage( Player, "Usage: /portal [WorldName]" ) - return true - end - - if( Player:MoveToWorld(Split[2]) == false ) then - SendMessageFailure( Player, "Could not move to world " .. Split[2] .. "!" ) - return true - end - - SendMessageSuccess( Player, "Moved successfully to '" .. Split[2] .. "'! :D" ) - return true - -end - -function HandleWorldsCommand( Split, Player ) - - local SettingsIni = cIniFile("settings.ini") - if SettingsIni:ReadFile() == false then - SendMessageFailure( Player, "No worlds found" ) - end - - Number = SettingsIni:NumValues("Worlds") - 1 - Worlds = {} - for i=0, SettingsIni:GetNumKeys() - 1 do - if SettingsIni:GetKeyName(i) == "Worlds" then - Key = i - break - end - end - - for i=0, Number do - table.insert( Worlds, SettingsIni:GetValue( Key, i ) ) - end - SendMessage( Player, "Found " .. #Worlds .. " worlds" ) - SendMessage( Player, table.concat( Worlds, ", " ) ) - return true - -end diff --git a/MCServer/Plugins/Core/rank-groups.lua b/MCServer/Plugins/Core/rank-groups.lua deleted file mode 100644 index 6233daa29..000000000 --- a/MCServer/Plugins/Core/rank-groups.lua +++ /dev/null @@ -1,63 +0,0 @@ -function HandleRankCommand( Split, Player ) - - if Split[2] == nil or Split[3] == nil then - SendMessage( Player, "Usage: /rank [Player] [Group]" ) - return true - end - - local GroupsIni = cIniFile( "groups.ini" ) - if GroupsIni:ReadFile() == false then - LOG( "Could not read groups.ini!" ) - end - - if GroupsIni:FindKey(Split[3]) == -1 then - SendMessageFailure( Player, "Group does not exist" ) - return true - end - - local UsersIni = cIniFile("users.ini") - if UsersIni:ReadFile() == false then - LOG( "Could not read users.ini!" ) - end - - UsersIni:DeleteKey( Split[2] ) - UsersIni:GetValueSet( Split[2], "Groups", Split[3] ) - UsersIni:WriteFile() - - local loopPlayers = function( Player ) - if Player:GetName() == Split[2] then - SendMessageSuccess( Player, "You were moved to group " .. Split[3] ) - Player:LoadPermissionsFromDisk() - end - end - - local loopWorlds = function ( World ) - World:ForEachPlayer( loopPlayers ) - end - - cRoot:Get():ForEachWorld( loopWorlds ) - SendMessageSuccess( Player, "Player " .. Split[2] .. " Was moved to " .. Split[3] ) - - return true - -end - -function HandleGroupsCommand( Split, Player ) - - local GroupsIni = cIniFile( "groups.ini" ) - if GroupsIni:ReadFile() == false then - SendMessageFailure( Player, "No groups found" ) - end - - Number = GroupsIni:NumKeys() - 1 - Groups = {} - for i=0, Number do - table.insert( Groups, GroupsIni:KeyName( i ) ) - end - - SendMessage( Player, "Found " .. #Groups .. " groups" ) - SendMessage( Player, table.concat( Groups, " " ) ) - - return true - -end diff --git a/MCServer/Plugins/Core/regen.lua b/MCServer/Plugins/Core/regen.lua deleted file mode 100644 index e76f5cb5c..000000000 --- a/MCServer/Plugins/Core/regen.lua +++ /dev/null @@ -1,20 +0,0 @@ -function HandleRegenCommand(Split, Player) - - if #Split == 2 or #Split > 3 then - SendMessage( Player, "Usage: '/regeneratechunk' or '/regeneratechunk [X] [Z]'" ) - return true - end - - local X = Player:GetChunkX() - local Z = Player:GetChunkZ() - - if #Split == 3 then - X = Split[2] - Z = Split[3] - end - - SendMessageSuccess( Player, "Regenerating chunk ["..X..", "..Z.."]") - Player:GetWorld():RegenerateChunk(X, Z) - return true - -end diff --git a/MCServer/Plugins/Core/save-reload-stop.lua b/MCServer/Plugins/Core/save-reload-stop.lua deleted file mode 100644 index 8c50da237..000000000 --- a/MCServer/Plugins/Core/save-reload-stop.lua +++ /dev/null @@ -1,28 +0,0 @@ -function HandleSaveAllCommand( Split, Player ) - - cRoot:Get():SaveAllChunks() - local Server = cRoot:Get():GetServer() - Server:SendMessage(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Saving all worlds!") - return true - -end - -function HandleStopCommand( Split, Player ) - - Server = cRoot:Get():GetServer() - local Server = cRoot:Get():GetServer() - Server:SendMessage(cChatColor.Red .. "[WARNING] " .. cChatColor.White .. "Server is terminating!" ) - cRoot:Get():QueueExecuteConsoleCommand("stop") - return true - -end - -function HandleReloadCommand( Split, Player ) - - Server = cRoot:Get():GetServer() - local Server = cRoot:Get():GetServer() - Server:SendMessage(cChatColor.Rose .. "[WARNING] " .. cChatColor.White .. "Reloading all plugins!" ) - cRoot:Get():GetPluginManager():ReloadPlugins() - return true - -end diff --git a/MCServer/Plugins/Core/spawn.lua b/MCServer/Plugins/Core/spawn.lua deleted file mode 100644 index 120c241fc..000000000 --- a/MCServer/Plugins/Core/spawn.lua +++ /dev/null @@ -1,9 +0,0 @@ -function HandleSpawnCommand(Split, Player) - - World = Player:GetWorld() - SetBackCoordinates(Player) - Player:TeleportToCoords(World:GetSpawnX(), World:GetSpawnY(), World:GetSpawnZ()) - SendMessageSuccess( Player, "Returned to world spawn" ) - return true - -end diff --git a/MCServer/Plugins/Core/teleport.lua b/MCServer/Plugins/Core/teleport.lua deleted file mode 100644 index 126801648..000000000 --- a/MCServer/Plugins/Core/teleport.lua +++ /dev/null @@ -1,74 +0,0 @@ -function HandleTPCommand(a_Split, a_Player) - - if #a_Split == 2 or #a_Split == 3 then - - -- Teleport to player specified in a_Split[2], tell them unless a_Split[3] equals "-h": - TeleportToPlayer( a_Player, a_Split[2], (a_Split[3] ~= "-h") ) - return true - - elseif #a_Split == 4 then - - -- Teleport to XYZ coords specified in a_Split[2, 3, 4]: - SetBackCoordinates(a_Player) - a_Player:TeleportToCoords( a_Split[2], a_Split[3], a_Split[4] ) - SendMessageSuccess( a_Player, "You teleported to [X:" .. a_Split[2] .. " Y:" .. a_Split[3] .. " Z:" .. a_Split[4] .. "]" ) - return true - - else - SendMessage( a_Player, "Usage: /tp [PlayerName] (-h) or /tp [X Y Z]" ) - return true - end - -end - -function HandleTPACommand( Split, Player ) - - if Split[2] == nil then - SendMessage( Player, "Usage: /tpa [Player]" ) - return true - end - - local loopPlayer = function( OtherPlayer ) - if OtherPlayer:GetName() == Split[2] then - SendMessage( OtherPlayer, Player:GetName() .. " send a teleport request" ) - SendMessageSuccess( Player, "You send a teleport request to " .. OtherPlayer:GetName() ) - Destination[OtherPlayer:GetName()] = Player:GetName() - end - end - - local loopWorlds = function( World ) - World:ForEachPlayer( loopPlayer ) - end - - cRoot:Get():ForEachWorld( loopWorlds ) - return true - -end - -function HandleTPAcceptCommand( Split, Player ) - - if Destination[Player:GetName()] == nil then - SendMessageFailure( Player, "Nobody has send you a teleport request" ) - return true - end - - local loopPlayer = function( OtherPlayer ) - if Destination[Player:GetName()] == OtherPlayer:GetName() then - if OtherPlayer:GetWorld():GetName() ~= Player:GetWorld():GetName() then - OtherPlayer:MoveToWorld( Player:GetWorld():GetName() ) - end - OtherPlayer:TeleportToEntity( Player ) - SendMessage( Player, OtherPlayer:GetName() .. " teleported to you" ) - SendMessageSuccess( OtherPlayer, "You teleported to " .. Player:GetName() ) - Destination[Player:GetName()] = nil - end - end - - local loopWorlds = function( World ) - World:ForEachPlayer( loopPlayer ) - end - - cRoot:Get():ForEachWorld( loopWorlds ) - return true - -end diff --git a/MCServer/Plugins/Core/tell.lua b/MCServer/Plugins/Core/tell.lua deleted file mode 100644 index 7d5a44f34..000000000 --- a/MCServer/Plugins/Core/tell.lua +++ /dev/null @@ -1,37 +0,0 @@ -function HandleTellCommand(Split, Player, OtherPlayer) - if (Split[2] == nil) or (Split[3] == nil) then - Player:SendMessage(cChatColor.Yellow .. "[INFO] " .. "Usage: /tell [playername] [message]") - return true - end - - local SendMessage = function(OtherPlayer) - - Sender = Player:GetName() - Reciever = Split[2] - - if (OtherPlayer:GetName() == Split[2]) then - Server = cRoot:Get():GetServer() - FullMsg = "" - - for i,v in ipairs(Split) do - if(i>2) then - if(FullMsg == "") then - FullMsg = v - else - FullMsg = FullMsg .. " " .. v - end - end - end - - Player:SendMessage(cChatColor.Green .. "[INFO] " .. "Message to player " .. Reciever .. " sent!" ) - OtherPlayer:SendMessage(cChatColor.Orange .. "[MSG: " .. Sender .. " ] " .. FullMsg ) - else - Player:SendMessage(cChatColor.Red .. 'Player "' ..Split[2].. '" not found') - end - end - - cRoot:Get():ForEachPlayer(SendMessage) - return true; -end - - diff --git a/MCServer/Plugins/Core/time.lua b/MCServer/Plugins/Core/time.lua deleted file mode 100644 index affc0656d..000000000 --- a/MCServer/Plugins/Core/time.lua +++ /dev/null @@ -1,26 +0,0 @@ -function HandleTimeCommand( Split, Player ) - - if Split[2] == nil then - SendMessage( Player, "Usage: /time [Day/Night/Set/Add]" ) - return true - end - - local Server = cRoot:Get():GetServer() - if string.upper( Split[2] ) == "DAY" then - Player:GetWorld():SetTimeOfDay( 0 ) - Server:SendMessage(cChatColor.Green .. "[INFO] " .. cChatColor.White .. "Time was set to daytime" ) - elseif string.upper( Split[2] ) == "NIGHT" then - Player:GetWorld():SetTimeOfDay( 12000 + 1000 ) - Server:SendMessage( cChatColor.Green .. "[INFO] " .. cChatColor.White .. "Time was set to night time" ) - elseif string.upper( Split[2] ) == "SET" and tonumber( Split[3] ) ~= nil then - Player:GetWorld():SetTimeOfDay( tonumber(Split[3]) ) - Server:SendMessage( cChatColor.Green .. "[INFO] " .. cChatColor.White .. "Time was set to " .. Split[3] ) - elseif string.upper( Split[2] ) == "ADD" and tonumber( Split[3] ) ~= nil then - Player:GetWorld():SetTimeOfDay( Player:GetWorld():GetTimeOfDay() + Split[3] ) - Server:SendMessage( cChatColor.Green .. "[INFO] " .. cChatColor.White .. Split[3] .. "Was added to the time" ) - else - SendMessage( Player, "Usage: /time [Day/Night/Set/Add]" ) - end - return true - -end diff --git a/MCServer/Plugins/Core/top.lua b/MCServer/Plugins/Core/top.lua deleted file mode 100644 index f85910475..000000000 --- a/MCServer/Plugins/Core/top.lua +++ /dev/null @@ -1,13 +0,0 @@ -function HandleTopCommand( Split, Player ) - - local World = Player:GetWorld() - - local PlayerPos = Player:GetPosition() - local Height = World:GetHeight( math.floor( PlayerPos.x ), math.floor( PlayerPos.z ) ) - SetBackCoordinates( Player ) - Player:TeleportToCoords( PlayerPos.x, Height+1, PlayerPos.z ) - SendMessageSuccess( Player, "Teleported to the topmost block" ) - - return true - -end diff --git a/MCServer/Plugins/Core/viewdistance.lua b/MCServer/Plugins/Core/viewdistance.lua deleted file mode 100644 index 9b2066cbf..000000000 --- a/MCServer/Plugins/Core/viewdistance.lua +++ /dev/null @@ -1,12 +0,0 @@ -function HandleViewDistanceCommand( Split, Player ) - - if( #Split ~= 2 ) then - SendMessage( Player, "Usage: /viewdistance [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."]" ) - return true - end - - Player:GetClientHandle():SetViewDistance( Split[2] ) - SendMessageSuccess( Player, "Your view distance has been set to " .. Player:GetClientHandle():GetViewDistance() ) - return true - -end diff --git a/MCServer/Plugins/Core/weather.lua b/MCServer/Plugins/Core/weather.lua deleted file mode 100644 index 4d33a7a11..000000000 --- a/MCServer/Plugins/Core/weather.lua +++ /dev/null @@ -1,33 +0,0 @@ -function HandleWeatherCommand(Split, Player) - - if #Split ~= 2 then - SendMessage( Player, "Usage: /weather [clear/rain/thunder]" ) - return true - end - - if (Split[2] == "clear") then - Player:GetWorld():SetWeather(0) - SendMessageSuccess( Player, "Downfall stopped" ) - elseif (Split[2] == "rain") then - Player:GetWorld():SetWeather(1) - SendMessageSuccess( Player, "Let it rain!" ) - elseif (Split[2] == "thunder") then - Player:GetWorld():SetWeather(2) - SendMessageSuccess( Player, "Thundery showers activate!") - end - - return true - -end - -function HandleDownfallCommand( Split, Player ) - World = Player:GetWorld() - if World:GetWeather() == 0 then - World:SetWeather(1) - else - World:SetWeather(0) - end - - SendMessageSuccess( Player, "Downfall Toggled") - -end diff --git a/MCServer/Plugins/Core/web_chat.lua b/MCServer/Plugins/Core/web_chat.lua deleted file mode 100644 index dfb17091e..000000000 --- a/MCServer/Plugins/Core/web_chat.lua +++ /dev/null @@ -1,157 +0,0 @@ -local CHAT_HISTORY = 50 -local LastMessageID = 0 - -local JavaScript = [[ - -]] - -local ChatLogMessages = {} - -function AddMessage( PlayerName, Message ) - LastMessageID = LastMessageID + 1 - table.insert( ChatLogMessages, { name = PlayerName, message = Message, id = LastMessageID } ) - while( #ChatLogMessages > CHAT_HISTORY ) do - table.remove( ChatLogMessages, 1 ) - end -end - -function OnChat( Player, Message ) - AddMessage( Player:GetName(), Message ) -end - -function HandleRequest_Chat( Request ) - if( Request.PostParams["JustChat"] ~= nil ) then - local LastIdx = 0 - if( Request.PostParams["LastMessageID"] ~= nil ) then LastIdx = tonumber( Request.PostParams["LastMessageID"] ) end - local Content = "" - for key, value in pairs(ChatLogMessages) do - if( value.id > LastIdx ) then - Content = Content .. "[" .. value.name .. "]: " .. value.message .. "
" - end - end - Content = Content .. "<>" .. LastMessageID .. "<>" .. LastIdx - return Content - end - - if( Request.PostParams["ChatMessage"] ~= nil ) then - if( Request.PostParams["ChatMessage"] == "/help" ) then - Commands = "Available commands" - AddMessage(Commands, "
" .. "/help, /reload" ) - return Commands - elseif( Request.PostParams["ChatMessage"] == "/reload" ) then - Server = cRoot:Get():GetServer() - Server:SendMessage( cChatColor.Green .. "Reloading all plugins." ) - AddMessage("Reloading all plugins", "") - cRoot:Get():GetPluginManager():ReloadPlugins() - return "" - else - cmd = Request.PostParams["ChatMessage"] - if string.sub(cmd,1,string.len("/")) == "/" then - AddMessage('Unknown Command "' .. Request.PostParams["ChatMessage"] .. '"', "") - return "" - end - end - local Message = "[WebAdmin]: " .. Request.PostParams["ChatMessage"] - cRoot:Get():GetServer():SendMessage( Message ) - AddMessage("WebAdmin", Request.PostParams["ChatMessage"] ) - return "" - end - - local Content = JavaScript - Content = Content .. [[ -
- - ]] - return Content -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/web_manageplugins.lua b/MCServer/Plugins/Core/web_manageplugins.lua deleted file mode 100644 index 543638183..000000000 --- a/MCServer/Plugins/Core/web_manageplugins.lua +++ /dev/null @@ -1,157 +0,0 @@ -local function Button_RemovePlugin( Name, Index ) - return "
" -end - -local function Button_EnablePlugin( Name ) - return [[
]] -end - -local function Button_DisablePlugin( Name ) - return [[
]] -end - -local function FindPluginID( SettingsIni, PluginName ) - local KeyIdx = SettingsIni:FindKey("Plugins") - local NumValues = SettingsIni:GetNumValues( KeyIdx ) - - for i = 0, NumValues-1 do - LOGINFO( SettingsIni:GetValue(KeyIdx, i) ) - if( SettingsIni:GetValue(KeyIdx, i) == PluginName ) then - return i - end - end - - return nil -end - -local function RemovePluginFromIni( SettingsIni, PluginName ) - local KeyIdx = SettingsIni:FindKey("Plugins") - local PluginIdx = FindPluginID( SettingsIni, PluginName ) - - if( PluginIdx == nil ) then - LOGINFO("Got nil! NOOOO") - return false - end - - local Name = SettingsIni:GetValue( KeyIdx, PluginIdx ) - if( Name ~= PluginName ) then - LOGINFO("not the same name T_T '" .. Name .. "' '" .. PluginName .. "'") - end - if( (Name == PluginName) and (SettingsIni:DeleteValueByID( KeyIdx, PluginIdx ) == true) ) then - return SettingsIni:WriteFile() - end - - return false -end - -local function AddPluginToIni( SettingsIni, PluginName ) - RemovePluginFromIni( SettingsIni, PluginName ) -- Make sure there are no duplicates - - if( SettingsIni:SetValue("Plugins", "Plugin", PluginName, true ) == true ) then - return SettingsIni:WriteFile() - end - - return false -end - -local function HandlePluginListChanges( Request, SettingsIni ) - local Content = "" - - if( Request.PostParams["EnablePlugin"] ~= nil - and Request.PostParams["PluginName"] ~= nil ) then - - local PluginName = Request.PostParams["PluginName"] - - local PM = cRoot:Get():GetPluginManager() - if( PM:LoadPlugin( PluginName ) == false ) then - Content = "Could not enable '".. PluginName .."'!" - end - - if( AddPluginToIni( SettingsIni, PluginName ) == true ) then - Content = "Enabled plugin '".. PluginName .."'" - else - Content = "Enabled plugin '".. PluginName .."' but could not add it to settings.ini" - end - - - elseif( Request.PostParams["DisablePlugin"] ~= nil - and Request.PostParams["PluginName"] ~= nil ) then - - local PluginName = Request.PostParams["PluginName"] - - local PM = cRoot:Get():GetPluginManager() - PM:DisablePlugin( PluginName ) - - if( RemovePluginFromIni( SettingsIni, PluginName ) == true ) then - Content = "Disabled plugin '".. PluginName .."'" - else - Content = "Disabled plugin '".. PluginName .."' but could not remove it from settings.ini" - end - - - - end - - if( #Content > 0 ) then - return "

INFO: " .. Content .. "

" - else - return "" - end -end - -function HandleRequest_ManagePlugins( Request ) - local Content = "" - - if( Request.PostParams["reload"] ~= nil ) then - Content = Content .. "" - Content = Content .. "

Reloading plugins... This can take a while depending on the plugins you're using.

" - cRoot:Get():GetPluginManager():ReloadPlugins() - return Content - end - - local SettingsIni = cIniFile("settings.ini") - if( SettingsIni:ReadFile() == true ) then - Content = Content .. HandlePluginListChanges( Request, SettingsIni ) - else - Content = Content .. "Cannot find/modify settings.ini" - end - - local PluginManager = cRoot:Get():GetPluginManager() - PluginManager:FindPlugins() -- Refreshes the plugin list - local PluginList = PluginManager:GetAllPlugins() - - Content = Content .. "

Currently installed plugins

" - Content = Content .. "" - ActivePluginsName = {} - ActivePluginVersion = {} - InactivePlugins = {} - for k, Plugin in pairs(PluginList) do - if( Plugin ) then - table.insert( ActivePluginsName, k ) - table.insert( ActivePluginVersion, Plugin:GetVersion() ) - else - table.insert( InactivePlugins, k ) - end - end - table.sort( ActivePluginsName ) - table.sort( InactivePlugins ) - for i = 1, #ActivePluginsName do - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - for i = 1, #InactivePlugins do - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - Content = Content .. "
".. ActivePluginsName[i] .."" .. ActivePluginsName[i] .. " V. " .. ActivePluginVersion[i] .. "" .. Button_DisablePlugin(ActivePluginsName[i]) .. "
".. InactivePlugins[i] .."" .. Button_EnablePlugin(InactivePlugins[i]) .. "
" - - Content = Content .. "

Reload

" - Content = Content .. "
" - Content = Content .. "

Click the reload button to reload all plugins according to settings.ini!" - Content = Content .. "

" - Content = Content .. "
" - - return Content -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/web_manageserver.lua b/MCServer/Plugins/Core/web_manageserver.lua deleted file mode 100644 index a2936c1a8..000000000 --- a/MCServer/Plugins/Core/web_manageserver.lua +++ /dev/null @@ -1,35 +0,0 @@ -function HandleRequest_ManageServer( Request ) - local Content = "" - if (Request.PostParams["RestartServer"] ~= nil) then - cRoot:Get():QueueExecuteConsoleCommand("restart"); - elseif (Request.PostParams["ReloadServer"] ~= nil) then - cRoot:Get():GetPluginManager():ReloadPlugins(); - elseif (Request.PostParams["StopServer"] ~= nil) then - cRoot:Get():QueueExecuteConsoleCommand("stop"); - elseif (Request.PostParams["WorldSaveAllChunks"] ~= nil) then - cRoot:Get():GetWorld(Request.PostParams["WorldSaveAllChunks"]):SaveAllChunks(); - end - Content = Content .. [[ -
- - -
-
-
- -
Manage Server
restart the server
reload the server
stop the server
- - - ]] - local LoopWorlds = function( World ) - Content = Content .. [[ -
- - ]] - end - cRoot:Get():ForEachWorld( LoopWorlds ) - Content = Content .. "
Manage Worlds
Save all the chunks of world ]] .. World:GetName() .. [[
" - - return Content -end - diff --git a/MCServer/Plugins/Core/web_permissions.lua b/MCServer/Plugins/Core/web_permissions.lua deleted file mode 100644 index dff35ca29..000000000 --- a/MCServer/Plugins/Core/web_permissions.lua +++ /dev/null @@ -1,134 +0,0 @@ -local function HTML_Option( value, text, selected ) - if( selected == true ) then - return [[]] - else - return [["]] - end -end - -local function ShowUsersTable() - local Content = "

Users

" - - local NumUsers = UsersIni:GetNumKeys() - - Content = Content .. "" - - if( NumUsers > 0 ) then - Content = Content .. "" - - for i=0, NumUsers-1 do - local UserName = UsersIni:GetKeyName( i ) - - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - else - Content = Content .. "" - end - Content = Content .. "
UserGroups
" .. i .. "." .. UserName .. "" - Content = Content .. UsersIni:GetValue( UserName, "Groups", "-" ) - Content = Content .. "
None
" - - - return Content -end - -local function ShowGroupsTable() - local Content = "

Groups

" - - local NumGroups = GroupsIni:GetNumKeys() - - Content = Content .. "" - if( NumGroups > 0 ) then - Content = Content .. "" - - for i=0, NumGroups-1 do - local GroupName = GroupsIni:GetKeyName( i ) - - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - else - Content = Content .. "" - end - Content = Content .. "
NamePermissionsColor
" .. i .. "." .. GroupName .. "" - Content = Content .. GroupsIni:GetValue( GroupName, "Permissions", "-" ) - Content = Content .. "" - Content = Content .. GroupsIni:GetValue( GroupName, "Color", "-" ) - Content = Content .. "
None
" - - return Content -end - -local function HTML_Select_Group( name, defaultValue ) - Groups = "" - for I=0, GroupsIni:GetNumKeys() - 1 do - Groups = Groups .. - HTML_Option(GroupsIni:KeyName(I), GroupsIni:KeyName(I), defaultValue == GroupsIni:KeyName(I) ) - end - return [[]] -end - - -local function AddPlayers( Request ) - local Content = "

Add or change Players

" - if( Request.PostParams["AddPlayerToGroup"] ~= nil ) then - if Request.PostParams["AddPlayer"] ~= "" then - if Request.PostParams["AddGroups"] ~= "" then - if GroupsIni:FindKey(Request.PostParams["AddGroup"]) == -1 then - return "Group does not exist" - end - UsersIni:DeleteKey(Request.PostParams["AddPlayer"]) - UsersIni:GetValueSet(Request.PostParams["AddPlayer"], "Groups", Request.PostParams["AddGroup"]) - UsersIni:WriteFile() - local loopPlayers = function( Player ) - if Player:GetName() == Request.PostParams["AddPlayer"] then - SendMessageSuccess( Player, "You were moved to group " .. Request.PostParams["AddGroup"] ) - Player:LoadPermissionsFromDisk() - end - end - local loopWorlds = function ( World ) - World:ForEachPlayer( loopPlayers ) - end - cRoot:Get():ForEachWorld( loopWorlds ) - end - end - end - Content = Content .. [[ - - - -
- - -
Player:
Group:]] .. HTML_Select_Group("AddGroup", GroupsIni:KeyName(0) ) .. [[
- ]] - - return Content -end - -function HandleRequest_Permissions( Request ) - GroupsIni = cIniFile("groups.ini") - if( GroupsIni:ReadFile() == false ) then - return "Could not read groups.ini!" - end - UsersIni = cIniFile("users.ini") - if( UsersIni:ReadFile() == false ) then - return "Could not read users.ini!" - end - - local Content = "" - - Content = Content .. AddPlayers( Request ) - Content = Content .. ShowGroupsTable() - Content = Content .. ShowUsersTable() - - return Content -end diff --git a/MCServer/Plugins/Core/web_playerlist.lua b/MCServer/Plugins/Core/web_playerlist.lua deleted file mode 100644 index 6ac25db86..000000000 --- a/MCServer/Plugins/Core/web_playerlist.lua +++ /dev/null @@ -1,38 +0,0 @@ -function HandleRequest_PlayerList( Request ) - local World = cRoot:Get():GetDefaultWorld() - local Content = "" - - if( Request.Params["playerlist-kick"] ~= nil ) then - local KickPlayerName = Request.Params["playerlist-kick"] - local FoundPlayerCallback = function( Player ) - if( Player:GetName() == KickPlayerName ) then - Player:GetClientHandle():Kick("You were kicked from the game!") - Content = Content .. "

" .. KickPlayerName .. " has been kicked from the game!

" - end - end - if( World:DoWithPlayer( KickPlayerName, FoundPlayerCallback ) == false ) then - Content = Content .. "

Could not find player " .. KickPlayerName .. " !

" - end - end - - Content = Content .. "

Connected Players: " .. World:GetNumPlayers() .. "

" - Content = Content .. "" - - local PlayerNum = 0 - local AddPlayerToTable = function( Player ) - PlayerNum = PlayerNum + 1 - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - cRoot:Get():ForEachPlayer( AddPlayerToTable ) - - if( PlayerNum == 0 ) then - Content = Content .. "" - end - Content = Content .. "
" .. PlayerNum .. "." .. Player:GetName() .. "Kick
None
" - Content = Content .. "
" - return Content -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/web_serversettings.lua b/MCServer/Plugins/Core/web_serversettings.lua deleted file mode 100644 index a53756b21..000000000 --- a/MCServer/Plugins/Core/web_serversettings.lua +++ /dev/null @@ -1,920 +0,0 @@ --- Some HTML helper functions -local function HTML_Option( value, text, selected ) - if( selected == true ) then - return [[]] - else - return [["]] - end -end - -local function HTML_Select_On_Off( name, defaultValue ) - return [[]] -end - -local function HTML_Select_Version( name, defaultValue ) - return [[]] -end - - -local function ShowGeneralSettings( Request ) - local Content = "" - local InfoMsg = nil - - local SettingsIni = cIniFile("settings.ini") - if( SettingsIni:ReadFile() == false ) then - InfoMsg = "ERROR: Could not read settings.ini!" - end - - if( Request.PostParams["general_submit"] ~= nil ) then - - SettingsIni:SetValue("Server", "Description",Request.PostParams["Server_Description"],false ) - if( tonumber( Request.PostParams["Server_MaxPlayers"] ) ~= nil ) then - SettingsIni:SetValue("Server", "MaxPlayers", Request.PostParams["Server_MaxPlayers"], false ) - end - if( tonumber( Request.PostParams["Server_Port"] ) ~= nil ) then - if( tonumber( Request.PostParams["Server_Port"] ) > 0 ) then - SettingsIni:SetValue("Server", "Port", Request.PostParams["Server_Port"], false ) - end - end - if( tonumber( Request.PostParams["Server_PortsIPv6"] ) ~= nil ) then - SettingsIni:SetValue("Server", "PortsIPv6", Request.PostParams["Server_PortsIPv6"], false ) - end - if( tonumber( Request.PostParams["Server_Version"] ) ~= nil ) then - SettingsIni:SetValue("Server", "PrimaryServerVersion", Request.PostParams["Server_Version"], false ) - end - if( tonumber( Request.PostParams["Authentication_Authenticate"] ) ~= nil ) then - SettingsIni:SetValue("Authentication", "Authenticate", Request.PostParams["Authentication_Authenticate"], false ) - end - - if( SettingsIni:WriteFile() == false ) then - InfoMsg = [[ERROR: Could not write to settings.ini!]] - else - InfoMsg = [[INFO: Successfully saved changes to settings.ini]] - end - end - - - Content = Content .. [[ - -

General Settings

]] - - if( InfoMsg ~= nil ) then - Content = Content .. "

" .. InfoMsg .. "

" - end - Content = Content .. [[ - - - - - - - - - - - - -
Server
Description:
Max Players:
Port:
PortsIPv6:
Shown Version:]] .. HTML_Select_Version("Server_Version", SettingsIni:GetValueI("Server", "PrimaryServerVersion") ) .. [[

- - - - - -
Authentication
Authenticate:]] .. HTML_Select_On_Off("Authentication_Authenticate", SettingsIni:GetValueI("Authentication", "Authenticate") ) .. [[

- - WARNING: Any changes made here might require a server restart in order to be applied! -
]] - - return Content -end - - -local function ShowMonstersSettings( Request ) - local Content = "" - local InfoMsg = nil - - local SettingsIni = cIniFile("settings.ini") - if( SettingsIni:ReadFile() == false ) then - InfoMsg = "ERROR: Could not read settings.ini!" - end - - if( Request.PostParams["monsters_submit"] ~= nil ) then - - if( tonumber( Request.PostParams["Monsters_AnimalsOn"] ) ~= nil ) then - SettingsIni:SetValue("Monsters", "AnimalsOn", Request.PostParams["Monsters_AnimalsOn"], false ) - end - if( tonumber( Request.PostParams["Monsters_AnimalSpawnInterval"] ) ~= nil ) then - SettingsIni:SetValue("Monsters", "AnimalSpawnInterval", Request.PostParams["Monsters_AnimalSpawnInterval"], false ) - end - SettingsIni:SetValue("Monsters", "Types", Request.PostParams["Monsters_Types"], false ) - if( SettingsIni:WriteFile() == false ) then - InfoMsg = "ERROR: Could not write to settings.ini!" - else - InfoMsg = "INFO: Successfully saved changes to settings.ini" - end - end - - - Content = Content .. "
" - - Content = Content .. "

Monsters Settings

" - if( InfoMsg ~= nil ) then - Content = Content .. "

" .. InfoMsg .. "

" - end - - Content = Content .. [[ - - - - - - - - -
Monsters
Animals On:]] .. HTML_Select_On_Off("Monsters_AnimalsOn", SettingsIni:GetValueI("Monsters", "AnimalsOn") ) .. [[
Animal Spawn Interval:
Monster Types:

- WARNING: Any changes made here might require a server restart in order to be applied! -
]] - - return Content -end - -local function ShowWorldsSettings( Request ) - local Content = "" - local InfoMsg = nil - local bSaveIni = false - - local SettingsIni = cIniFile("settings.ini") - if( SettingsIni:ReadFile() == false ) then - InfoMsg = [[ERROR: Could not read settings.ini!]] - end - - if( Request.PostParams["RemoveWorld"] ~= nil ) then - Content = Content .. Request.PostParams["RemoveWorld"] - local WorldIdx = string.sub( Request.PostParams["RemoveWorld"], string.len("Remove ") ) - local KeyIdx = SettingsIni:FindKey("Worlds") - local WorldName = SettingsIni:GetValue( KeyIdx, WorldIdx ) - if( SettingsIni:DeleteValueByID( KeyIdx, WorldIdx ) == true ) then - InfoMsg = "INFO: Successfully removed world " .. WorldName .. "!
" - bSaveIni = true - end - end - - if( Request.PostParams["AddWorld"] ~= nil ) then - if( Request.PostParams["WorldName"] ~= nil and Request.PostParams["WorldName"] ~= "" ) then - SettingsIni:SetValue("Worlds", "World", Request.PostParams["WorldName"], true ) - InfoMsg = "INFO: Successfully added world " .. Request.PostParams["WorldName"] .. "!
" - bSaveIni = true - end - end - - if( Request.PostParams["worlds_submit"] ~= nil ) then - SettingsIni:SetValue("Worlds", "DefaultWorld", Request.PostParams["Worlds_DefaultWorld"], false ) - if( Request.PostParams["Worlds_World"] ~= nil ) then - SettingsIni:SetValue("Worlds", "World", Request.PostParams["Worlds_World"], true ) - end - bSaveIni = true - end - - if( bSaveIni == true ) then - if( InfoMsg == nil ) then InfoMsg = "" end - if( SettingsIni:WriteFile() == false ) then - InfoMsg = InfoMsg .. "ERROR: Could not write to settings.ini!" - else - InfoMsg = InfoMsg .. "INFO: Successfully saved changes to settings.ini" - end - end - - Content = Content .. "

Worlds Settings

" - if( InfoMsg ~= nil ) then - Content = Content .. "

" .. InfoMsg .. "

" - end - - Content = Content .. [[ -
- - - - ]] - - local KeyIdx = SettingsIni:FindKey("Worlds") - local NumValues = SettingsIni:GetNumValues( KeyIdx ) - for i = 0, NumValues-1 do - local ValueName = SettingsIni:GetValueName(KeyIdx, i ) - if( ValueName == "World" ) then - local WorldName = SettingsIni:GetValue(KeyIdx, i) - Content = Content .. [[ - ]] - end - end - - Content = Content .. [[ - - -
Worlds
Default World:
]] .. ValueName .. [[:
]] .. WorldName .. [[
Add World:

- - WARNING: Any changes made here might require a server restart in order to be applied! -
]] - return Content -end - -local function SelectWorldButton( WorldName ) - return "
" -end - -local function HTML_Select_Dimension( name, defaultValue ) - return [[]] -end - -local function HTML_Select_Scheme( name, defaultValue ) - return [[]] -end - -local function HTML_Select_GameMode( name, defaultValue ) - return [[]] -end - -local function HTML_Select_Simulator( name, defaultValue ) - return [[]] -end - -local function HTML_Select_BiomeGen( name, defaultValue ) - return [[]] -end - -local function HTML_Select_HeightGen( name, defaultValue ) - return [[]] -end - -local function HTML_Select_CompositionGen( name, defaultValue ) - return [[]] -end - -local function HTML_Select_Generator( name, defaultValue ) - return [[]] -end - -local function HTML_Select_Biome( name, defaultValue ) - return [[]] -end - -function ShowWorldSettings( Request ) - local Content = "" - local InfoMsg = nil - local SettingsIni = cIniFile("settings.ini") - if( SettingsIni:ReadFile() == false ) then - InfoMsg = [[ERROR: Could not read settings.ini!]] - end - if (Request.PostParams["SelectWorld"] ~= nil and Request.PostParams["WorldName"] ~= nil) then -- World is selected! - WORLD = Request.PostParams["WorldName"] - SelectedWorld = cRoot:Get():GetWorld(WORLD) - elseif SelectedWorld == nil then - WORLD = SettingsIni:GetValue("Worlds", "DefaultWorld") - SelectedWorld = cRoot:Get():GetWorld( WORLD ) - end - local WorldIni = cIniFile(SelectedWorld:GetName() .. "/world.ini") - WorldIni:ReadFile() - if (Request.PostParams["world_submit"]) ~= nil then - if( tonumber( Request.PostParams["World_Dimension"] ) ~= nil ) then - WorldIni:DeleteValue( "General", "Dimension" ) - WorldIni:SetValue( "General", "Dimension", Request.PostParams["World_Dimension"] ) - end - if( tonumber( Request.PostParams["World_Schema"] ) ~= nil ) then - WorldIni:DeleteValue( "General", "Schema" ) - WorldIni:SetValue( "General", "Schema", Request.PostParams["World_Schema"] ) - end - if( tonumber( Request.PostParams["World_SpawnX"] ) ~= nil ) then - WorldIni:DeleteValue( "SpawnPosition", "X" ) - WorldIni:SetValue( "SpawnPosition", "X", Request.PostParams["World_SpawnX"] ) - end - if( tonumber( Request.PostParams["World_SpawnY"] ) ~= nil ) then - WorldIni:DeleteValue( "SpawnPosition", "Y" ) - WorldIni:SetValue( "SpawnPosition", "Y", Request.PostParams["World_SpawnY"] ) - end - if( tonumber( Request.PostParams["World_SpawnZ"] ) ~= nil ) then - WorldIni:DeleteValue( "SpawnPosition", "Z" ) - WorldIni:SetValue( "SpawnPosition", "Z", Request.PostParams["World_SpawnZ"] ) - end - if( tonumber( Request.PostParams["LimitWorldWidth"] ) ~= nil ) then - WorldIni:DeleteValue( "WorldLimit", "LimitRadius" ) - WorldIni:SetValue( "WorldLimit", "LimitRadius", Request.PostParams["LimitWorldWidth"] ) - end - if( tonumber( Request.PostParams["World_Seed"] ) ~= nil ) then - WorldIni:DeleteValue( "Seed", "Seed" ) - WorldIni:SetValue( "Seed", "Seed", Request.PostParams["World_Seed"] ) - end - if( tonumber( Request.PostParams["World_PVP"] ) ~= nil ) then - WorldIni:DeleteValue( "PVP", "Enabled" ) - WorldIni:SetValue( "PVP", "Enabled", Request.PostParams["World_PVP"] ) - end - if( tonumber( Request.PostParams["World_GameMode"] ) ~= nil ) then - WorldIni:DeleteValue( "GameMode", "GameMode" ) - WorldIni:SetValue( "GameMode", "GameMode", Request.PostParams["World_GameMode"] ) - end - if( tonumber( Request.PostParams["World_DeepSnow"] ) ~= nil ) then - WorldIni:DeleteValue( "Physics", "DeepSnow" ) - WorldIni:SetValue( "Physics", "DeepSnow", Request.PostParams["World_DeepSnow"] ) - end - if( tonumber( Request.PostParams["World_SandInstantFall"] ) ~= nil ) then - WorldIni:DeleteValue( "Physics", "SandInstantFall" ) - WorldIni:SetValue( "Physics", "SandInstantFall", Request.PostParams["World_SandInstantFall"] ) - end - if( tonumber( Request.PostParams["World_WaterSimulator"] ) ~= nil ) then - WorldIni:DeleteValue( "Physics", "WaterSimulator" ) - WorldIni:SetValue( "Physics", "WaterSimulator", Request.PostParams["World_WaterSimulator"] ) - end - if( tonumber( Request.PostParams["World_LavaSimulator"] ) ~= nil ) then - WorldIni:DeleteValue( "Physics", "LavaSimulator" ) - WorldIni:SetValue( "Physics", "LavaSimulator", Request.PostParams["World_LavaSimulator"] ) - end - if( tonumber( Request.PostParams["World_MaxSugarcaneHeight"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "MaxSugarcaneHeight" ) - WorldIni:SetValue( "Plants", "MaxSugarcaneHeight", Request.PostParams["World_MaxSugarcaneHeight"] ) - end - if( tonumber( Request.PostParams["World_MaxCactusHeight"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "MaxCactusHeight" ) - WorldIni:SetValue( "Plants", "MaxCactusHeight", Request.PostParams["World_MaxCactusHeight"] ) - end - if( tonumber( Request.PostParams["World_CarrotsBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsCarrotsBonemealable" ) - WorldIni:SetValue( "Plants", "IsCarrotsBonemealable", Request.PostParams["World_CarrotsBonemealable"] ) - end - if( tonumber( Request.PostParams["World_CropsBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsCropsBonemealable" ) - WorldIni:SetValue( "Plants", "IsCropsBonemealable", Request.PostParams["World_CropsBonemealable"] ) - end - if( tonumber( Request.PostParams["World_GrassBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsGrassBonemealable" ) - WorldIni:SetValue( "Plants", "IsGrassBonemealable", Request.PostParams["World_GrassBonemealable"] ) - end - if( tonumber( Request.PostParams["World_SaplingBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsSaplingBonemealable" ) - WorldIni:SetValue( "Plants", "IsSaplingBonemealable", Request.PostParams["World_SaplingBonemealable"] ) - end - if( tonumber( Request.PostParams["World_MelonStemBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsMelonStemBonemealable" ) - WorldIni:SetValue( "Plants", "IsMelonStemBonemealable", Request.PostParams["World_MelonStemBonemealable"] ) - end - if( tonumber( Request.PostParams["World_MelonBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsMelonBonemealable" ) - WorldIni:SetValue( "Plants", "IsMelonBonemealable", Request.PostParams["World_MelonBonemealable"] ) - end - if( tonumber( Request.PostParams["World_PotatoesBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsPotatoesBonemealable" ) - WorldIni:SetValue( "Plants", "IsPotatoesBonemealable", Request.PostParams["World_PotatoesBonemealable"] ) - end - if( tonumber( Request.PostParams["World_PumpkinStemBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsPumpkinStemBonemealable" ) - WorldIni:SetValue( "Plants", "IsPumpkinStemBonemealable", Request.PostParams["World_PumpkinStemBonemealable"] ) - end - if( tonumber( Request.PostParams["World_PumpkinBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsPumpkinBonemealable" ) - WorldIni:SetValue( "Plants", "IsPumpkinBonemealable", Request.PostParams["World_PumpkinBonemealable"] ) - end - if( tonumber( Request.PostParams["World_SugarCaneBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsSugarCaneBonemealable" ) - WorldIni:SetValue( "Plants", "IsSugarCaneBonemealable", Request.PostParams["World_SugarCaneBonemealable"] ) - end - if( tonumber( Request.PostParams["World_CactusBonemealable"] ) ~= nil ) then - WorldIni:DeleteValue( "Plants", "IsCactusBonemealable" ) - WorldIni:SetValue( "Plants", "IsCactusBonemealable", Request.PostParams["World_CactusBonemealable"] ) - end - if( ( Request.PostParams["World_BiomeGen"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "BiomeGen" ) - WorldIni:SetValue( "Generator", "BiomeGen", Request.PostParams["World_BiomeGen"] ) - end - if( ( Request.PostParams["World_Biome"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ConstantBiome" ) - WorldIni:SetValue( "Generator", "ConstantBiome", Request.PostParams["World_Biome"] ) - end - if( ( Request.PostParams["World_MultiStepMapOceanCellSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MultiStepMapOceanCellSize" ) - WorldIni:SetValue( "Generator", "MultiStepMapOceanCellSize", Request.PostParams["World_MultiStepMapOceanCellSize"] ) - end - if( ( Request.PostParams["World_MultiStepMapMushroomIslandSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MultiStepMapMushroomIslandSize" ) - WorldIni:SetValue( "Generator", "MultiStepMapMushroomIslandSize", Request.PostParams["World_MultiStepMapMushroomIslandSize"] ) - end - if( ( Request.PostParams["World_MultiStepMapRiverCellSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MultiStepMapRiverCellSize" ) - WorldIni:SetValue( "Generator", "MultiStepMapRiverCellSize", Request.PostParams["World_MultiStepMapRiverCellSize"] ) - end - if( ( Request.PostParams["World_MultiStepMapRiverWidth"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MultiStepMapRiverWidth" ) - WorldIni:SetValue( "Generator", "MultiStepMapRiverWidth", Request.PostParams["World_MultiStepMapRiverWidth"] ) - end - if( ( Request.PostParams["World_MultiStepMapLandBiomeSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MultiStepMapLandBiomeSize" ) - WorldIni:SetValue( "Generator", "MultiStepMapLandBiomeSize", Request.PostParams["World_MultiStepMapLandBiomeSize"] ) - end - if( ( Request.PostParams["World_DistortedVoronoiCellSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "DistortedVoronoiCellSize" ) - WorldIni:SetValue( "Generator", "DistortedVoronoiCellSize", Request.PostParams["World_DistortedVoronoiCellSize"] ) - end - if( ( Request.PostParams["World_DistortedVoronoiBiomes"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "DistortedVoronoiBiomes" ) - WorldIni:SetValue( "Generator", "DistortedVoronoiBiomes", Request.PostParams["World_DistortedVoronoiBiomes"] ) - end - if( ( Request.PostParams["World_VoronoiCellSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "VoronoiCellSize" ) - WorldIni:SetValue( "Generator", "VoronoiCellSize", Request.PostParams["World_VoronoiCellSize"] ) - end - if( ( Request.PostParams["World_VoronoiBiomesdVoronoiBiomes"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "VoronoiBiomes" ) - WorldIni:SetValue( "Generator", "VoronoiBiomes", Request.PostParams["World_VoronoiBiomes"] ) - end - if( ( Request.PostParams["World_CheckerBoardBiomes"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "CheckerBoardBiomes" ) - WorldIni:SetValue( "Generator", "CheckerBoardBiomes", Request.PostParams["World_CheckerBoardBiomes"] ) - end - if( ( Request.PostParams["World_CheckerBoardBiomeSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "CheckerBoardBiomeSize" ) - WorldIni:SetValue( "Generator", "CheckerBoardBiomeSize", Request.PostParams["World_CheckerBoardBiomeSize"] ) - end - if( ( Request.PostParams["World_HeightGen"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "HeightGen" ) - WorldIni:SetValue( "Generator", "HeightGen", Request.PostParams["World_HeightGen"] ) - end - if( ( Request.PostParams["World_FlatHeight"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "FlatHeight" ) - WorldIni:SetValue( "Generator", "FlatHeight", Request.PostParams["World_FlatHeight"] ) - end - if( ( Request.PostParams["World_CompositionGen"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "CompositionGen" ) - WorldIni:SetValue( "Generator", "CompositionGen", Request.PostParams["World_CompositionGen"] ) - end - if( ( Request.PostParams["World_Noise3DSeaLevel"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DSeaLevel" ) - WorldIni:SetValue( "Generator", "Noise3DSeaLevel", Request.PostParams["World_Noise3DSeaLevel"] ) - end - if( ( Request.PostParams["World_Noise3DHeightAmplification"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DHeightAmplification" ) - WorldIni:SetValue( "Generator", "Noise3DHeightAmplification", Request.PostParams["World_Noise3DHeightAmplification"] ) - end - if( ( Request.PostParams["World_Noise3DMidPoint"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DMidPoint" ) - WorldIni:SetValue( "Generator", "Noise3DMidPoint", Request.PostParams["World_Noise3DMidPoint"] ) - end - if( ( Request.PostParams["World_Noise3DFrequencyX"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DFrequencyX" ) - WorldIni:SetValue( "Generator", "Noise3DFrequencyX", Request.PostParams["World_Noise3DFrequencyX"] ) - end - if( ( Request.PostParams["World_Noise3DFrequencyY"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DFrequencyY" ) - WorldIni:SetValue( "Generator", "Noise3DFrequencyY", Request.PostParams["World_Noise3DFrequencyY"] ) - end - if( ( Request.PostParams["World_Noise3DFrequencyZ"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DFrequencyZ" ) - WorldIni:SetValue( "Generator", "Noise3DFrequencyZ", Request.PostParams["World_Noise3DFrequencyZ"] ) - end - if( ( Request.PostParams["World_Noise3DAirThreshold"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Noise3DAirThreshold" ) - WorldIni:SetValue( "Generator", "Noise3DAirThreshold", Request.PostParams["World_Noise3DAirThreshold"] ) - end - if( ( Request.PostParams["World_ClassicSeaLevel"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicSeaLevel" ) - WorldIni:SetValue( "Generator", "ClassicSeaLevel", Request.PostParams["World_ClassicSeaLevel"] ) - end - if( ( Request.PostParams["World_ClassicBeachHeight"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBeachHeight" ) - WorldIni:SetValue( "Generator", "ClassicBeachHeight", Request.PostParams["World_ClassicBeachHeight"] ) - end - if( ( Request.PostParams["World_ClassicBeachDepth"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBeachDepth" ) - WorldIni:SetValue( "Generator", "ClassicBeachDepth", Request.PostParams["World_ClassicBeachDepth"] ) - end - if( ( Request.PostParams["World_ClassicBlockTop"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockTop" ) - WorldIni:SetValue( "Generator", "ClassicBlockTop", Request.PostParams["World_ClassicBlockTop"] ) - end - if( ( Request.PostParams["World_ClassicBlockMiddle"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockMiddle" ) - WorldIni:SetValue( "Generator", "ClassicBlockMiddle", Request.PostParams["World_ClassicBlockMiddle"] ) - end - if( ( Request.PostParams["World_ClassicBlockBottom"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockBottom" ) - WorldIni:SetValue( "Generator", "ClassicBlockBottom", Request.PostParams["World_ClassicBlockBottom"] ) - end - if( ( Request.PostParams["World_ClassicBlockBeach"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockBeach" ) - WorldIni:SetValue( "Generator", "ClassicBlockBeach", Request.PostParams["World_ClassicBlockBeach"] ) - end - if( ( Request.PostParams["World_ClassicBlockBeachBottom"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockBeachBottom" ) - WorldIni:SetValue( "Generator", "ClassicBlockBeachBottom", Request.PostParams["World_ClassicBlockBeachBottom"] ) - end - if( ( Request.PostParams["World_ClassicBlockSea"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "ClassicBlockSea" ) - WorldIni:SetValue( "Generator", "ClassicBlockSea", Request.PostParams["World_ClassicBlockSea"] ) - end - if( ( Request.PostParams["World_SameBlockType"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "SameBlockType" ) - WorldIni:SetValue( "Generator", "SameBlockType", Request.PostParams["World_SameBlockType"] ) - end - if( ( Request.PostParams["World_SameBlockBedrocked"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "SameBlockBedrocked" ) - WorldIni:SetValue( "Generator", "SameBlockBedrocked", Request.PostParams["World_SameBlockBedrocked"] ) - end - if( ( Request.PostParams["World_Structures"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Structures" ) - WorldIni:SetValue( "Generator", "Structures", Request.PostParams["World_Structures"] ) - end - if( ( Request.PostParams["World_Finishers"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Finishers" ) - WorldIni:SetValue( "Generator", "Finishers", Request.PostParams["World_Finishers"] ) - end - if( ( Request.PostParams["World_Generator"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "Generator" ) - WorldIni:SetValue( "Generator", "Generator", Request.PostParams["World_Generator"] ) - end - if( ( Request.PostParams["World_MineShaftsGridSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MineShaftsGridSize" ) - WorldIni:SetValue( "Generator", "MineShaftsGridSize", Request.PostParams["World_MineShaftsGridSize"] ) - end - if( ( Request.PostParams["World_MineShaftsMaxSystemSize"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MineShaftsMaxSystemSize" ) - WorldIni:SetValue( "Generator", "MineShaftsMaxSystemSize", Request.PostParams["World_MineShaftsMaxSystemSize"] ) - end - if( ( Request.PostParams["World_MineShaftsChanceCorridor"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MineShaftsChanceCorridor" ) - WorldIni:SetValue( "Generator", "MineShaftsChanceCorridor", Request.PostParams["World_MineShaftsChanceCorridor"] ) - end - if( ( Request.PostParams["World_MineShaftsChanceCrossing"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MineShaftsChanceCrossing" ) - WorldIni:SetValue( "Generator", "MineShaftsChanceCrossing", Request.PostParams["World_MineShaftsChanceCrossing"] ) - end - if( ( Request.PostParams["World_MineShaftsChanceStaircase"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "MineShaftsChanceStaircase" ) - WorldIni:SetValue( "Generator", "MineShaftsChanceStaircase", Request.PostParams["World_MineShaftsChanceStaircase"] ) - end - if( ( Request.PostParams["World_LavaLakesProbability"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "LavaLakesProbability" ) - WorldIni:SetValue( "Generator", "LavaLakesProbability", Request.PostParams["World_LavaLakesProbability"] ) - end - if( ( Request.PostParams["World_WaterLakesProbability"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "WaterLakesProbability" ) - WorldIni:SetValue( "Generator", "WaterLakesProbability", Request.PostParams["World_WaterLakesProbability"] ) - end - if( ( Request.PostParams["World_BottomLavaLevel"] ) ~= nil ) then - WorldIni:DeleteValue( "Generator", "BottomLavaLevel" ) - WorldIni:SetValue( "Generator", "BottomLavaLevel", Request.PostParams["World_BottomLavaLevel"] ) - end - - WorldIni:WriteFile() - end - Content = Content .. "

World for operations: " .. WORLD .. "

" - Content = Content .. "" - local WorldNum = 0 - local AddWorldToTable = function(World) - WorldNum = WorldNum + 1 - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end - cRoot:Get():ForEachWorld(AddWorldToTable) - Content = Content .. "
" .. WorldNum .. "." .. World:GetName() .. "" .. SelectWorldButton(World:GetName()) .. "
" - - - Content = Content .. [[ - -
- - - -
General
Dimension:]] .. HTML_Select_Dimension("World_Dimension", WorldIni:GetValueI("General", "Dimension") ) .. [[
-
- - - - -
Storage
Schema:]] .. HTML_Select_Scheme("World_Schema", WorldIni:GetValueI("Storage", "Schema") ) .. [[
-
- - - - - - - - -
Spawn Position
X:
Y:
Z:
-
- - - - -
LimitWorld
Max chunks from spawn (0 to disable):

- - - - -
Seed
Seed:
-
- - - - -
PVP
PVP:]] .. HTML_Select_On_Off("World_PVP", WorldIni:GetValueI("PVP", "Enabled") ) .. [[
-
- - - - -
GameMode
GameMode:]] .. HTML_Select_GameMode("World_GameMode", WorldIni:GetValueI("GameMode", "GameMode") ) .. [[
-
- - - - - - - - - - -
Physics
DeepSnow:]] .. HTML_Select_On_Off("World_DeepSnow", WorldIni:GetValueI("Physics", "DeepSnow") ) .. [[
SandInstantFall:]] .. HTML_Select_On_Off("World_SandInstantFall", WorldIni:GetValueI("Physics", "SandInstantFall") ) .. [[
WaterSimulator:]] .. HTML_Select_Simulator("World_WaterSimulator", WorldIni:GetValue("Physics", "WaterSimulator") ) .. [[
LavaSimulator:]] .. HTML_Select_Simulator("World_LavaSimulator", WorldIni:GetValue("Physics", "LavaSimulator") ) .. [[
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Plants
MaxCactusHeight:
MaxSugarcaneHeigh:
CarrotsBonemealable:]] .. HTML_Select_On_Off("World_CarrotsBonemealable", WorldIni:GetValueI("Plants", "IsCarrotsBonemealable") ) .. [[
CropsBonemealable:]] .. HTML_Select_On_Off("World_CropsBonemealable", WorldIni:GetValueI("Plants", "IsCropsBonemealable") ) .. [[
GrassBonemealabl:]] .. HTML_Select_On_Off("World_GrassBonemealable", WorldIni:GetValueI("Plants", "IsGrassBonemealable") ) .. [[
SaplingBonemealable:]] .. HTML_Select_On_Off("World_SaplingBonemealable", WorldIni:GetValueI("Plants", "IsSaplingBonemealable") ) .. [[
MelonStemBonemealable:]] .. HTML_Select_On_Off("World_MelonStemBonemealable", WorldIni:GetValueI("Plants", "IsMelonStemBonemealable") ) .. [[
MelonBonemealable:]] .. HTML_Select_On_Off("World_MelonBonemealable", WorldIni:GetValueI("Plants", "IsMelonBonemealable") ) .. [[
PotatoesBonemealable:]] .. HTML_Select_On_Off("World_PotatoesBonemealable", WorldIni:GetValueI("Plants", "IsPotatoesBonemealable") ) .. [[
PumpkinStemBonemealable:]] .. HTML_Select_On_Off("World_PumpkinStemBonemealable", WorldIni:GetValueI("Plants", "IsPumpkinStemBonemealable") ) .. [[
PumpkinBonemealable:]] .. HTML_Select_On_Off("World_PumpkinBonemealable", WorldIni:GetValueI("Plants", "IsPumpkinBonemealable") ) .. [[
SugarcaneBonemealabl:]] .. HTML_Select_On_Off("World_SugarcaneBonemealable", WorldIni:GetValueI("Plants", "IsSugarcaneBonemealable") ) .. [[
CactusBonemealable:]] .. HTML_Select_On_Off("World_CactusBonemealable", WorldIni:GetValueI("Plants", "IsCactusBonemealable") ) .. [[
-
- - - - - - - - - - - - - - - -
Generator
BiomeGen:]] .. HTML_Select_BiomeGen("World_BiomeGen", WorldIni:GetValue("Generator", "BiomeGen") ) .. [[
HeightGen:]] .. HTML_Select_HeightGen("World_HeightGen", WorldIni:GetValue("Generator", "HeightGen") ) .. [[
CompositionGen:]] .. HTML_Select_CompositionGen("World_CompositionGen", WorldIni:GetValue("Generator", "CompositionGen") ) .. [[
Structures:
Finishers:
Generator:]] .. HTML_Select_Generator("World_Generator", WorldIni:GetValue("Generator", "Generator") ) .. [[
-
- -
-
Finetuning
- - ]] - if WorldIni:GetValue( "Generator", "BiomeGen" ) == "Constant" then - Content = Content .. [[ - - - ]] - elseif WorldIni:GetValue( "Generator", "BiomeGen" ) == "MultiStepMap" then - Content = Content .. [[ - - - - - - - - - - - ]] - elseif WorldIni:GetValue( "Generator", "BiomeGen" ) == "DistortedVoronoi" then - Content = Content .. [[ - - - - - ]] - elseif WorldIni:GetValue( "Generator", "BiomeGen" ) == "Voronoi" then - Content = Content .. [[ - - - - - ]] - elseif WorldIni:GetValue( "Generator", "BiomeGen" ) == "CheckerBoard" then - Content = Content .. [[ - - - - - ]] - end - - if WorldIni:GetValue( "Generator", "CompositionGen" ) == "Noise3D" then - Content = Content .. [[ - - - - - - - - - - - - - - - ]] - elseif WorldIni:GetValue( "Generator", "CompositionGen" ) == "Classic" then - Content = Content .. [[ - - - - - - - - - - - - - - - - - - - ]] - elseif WorldIni:GetValue( "Generator", "CompositionGen" ) == "SameBlock" then - Content = Content .. [[ - - - - - ]] - end - if WorldIni:GetValue( "Generator", "HeightGen" ) == "Flat" then - Content = Content .. [[ - - - ]] - end - if string.find( WorldIni:GetValue( "Generator", "Structures" ), "MineShafts" ) ~= nil then - Content = Content .. [[ - - - - - - - - - - - ]] - end - if string.find( WorldIni:GetValue( "Generator", "Structures" ), "LavaLakes" ) ~= nil then - Content = Content .. [[ - - - ]] - end - if string.find( WorldIni:GetValue( "Generator", "Structures" ), "WaterLakes" ) ~= nil then - Content = Content .. [[ - - - ]] - end - if string.find( WorldIni:GetValue( "Generator", "Finishers" ), "BottomLava" ) ~= nil then - Content = Content .. [[ - - - ]] - end - Content = Content .. [[
Biome Generator
ConstantBiome:]] .. HTML_Select_Biome( "World_Biome", WorldIni:GetValue("Generator", "ConstantBiome" ) ) .. [[
Biome Generator
MultiStepMapOceanCellSize:
MultiStepMapOceanCellSize:
MultiStepMapOceanCellSize:
MultiStepMapOceanCellSize:
MultiStepMapOceanCellSize:
Biome Generator
DistortedVoronoiCellSize:
DistortedVoronoiBiomes:
Biome Generator
VoronoiCellSize:
VoronoiBiomes:
Biome Generator
CheckerBoardBiomes:
CheckerBoardBiomeSize:
Composition Generator
Noise3DSeaLevel:
Noise3DHeightAmplification:
Noise3DMidPoint:
Noise3DFrequencyX:
Noise3DFrequencyY:
Noise3DFrequencyZ:
Noise3DAirThreshold:
Composition Generator
ClassicSeaLevel:
ClassicBeachHeight:
ClassicBeachDepth:
ClassicBlockTop:
ClassicBlockMiddle:
ClassicBlockBottom:
ClassicBlockBeach:
ClassicBlockBeachBottom:
ClassicBlockSea:
Composition Generator
SameBlockType:
SameBlockBedrocked:
Height Generator
FlatHeight:
MineShafts
MineShaftsGridSize:
MineShaftsMaxSystemSize:
MineShaftsChanceCorridor:
MineShaftsChanceCrossing:
MineShaftsChanceStaircase:
LavaLakes
LavaLakesProbability:
WaterLakes
WaterLakesProbability:
BottomLavaLevel
BottomLavaLevel:
]] - - Content = Content .. [[
- WARNING: Any changes made here might require a server restart in order to be applied! - ]] - return Content -end - - - -function HandleRequest_ServerSettings( Request ) - local Content = "" - - Content = Content .. [[ -

Server Settings

- - - - - - - -
GeneralMonstersWorldsWorld
-
]] - - if( Request.Params["tab"] == "Monsters" ) then - Content = Content .. ShowMonstersSettings( Request ) - elseif( Request.Params["tab"] == "Worlds" ) then - Content = Content .. ShowWorldsSettings( Request ) - elseif( Request.Params["tab"] == "World" ) then - Content = Content .. ShowWorldSettings( Request ) - else - Content = Content .. ShowGeneralSettings( Request ) -- Default to general settings - end - - return Content -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/web_whitelist.lua b/MCServer/Plugins/Core/web_whitelist.lua deleted file mode 100644 index 61cc6fd8b..000000000 --- a/MCServer/Plugins/Core/web_whitelist.lua +++ /dev/null @@ -1,79 +0,0 @@ -local function HTMLDeleteButton( name ) - return "
" -end - -function HandleRequest_WhiteList( Request ) - local UpdateMessage = "" - if( Request.PostParams["whitelist-add"] ~= nil ) then - local PlayerName = Request.PostParams["whitelist-add"] - - if( WhiteListIni:GetValueB("WhiteList", PlayerName, false) == true ) then - UpdateMessage = "".. PlayerName.." is already on the whitelist" - else - WhiteListIni:SetValueB("WhiteList", PlayerName, true ) - UpdateMessage = "Added " .. PlayerName .. " to whitelist." - WhiteListIni:WriteFile() - end - elseif( Request.PostParams["whitelist-delete"] ~= nil ) then - local PlayerName = Request.PostParams["whitelist-delete"] - WhiteListIni:DeleteValue( "WhiteList", PlayerName ) - UpdateMessage = "Removed " .. PlayerName .. " from whitelist." - WhiteListIni:WriteFile() - elseif( Request.PostParams["whitelist-reload"] ~= nil ) then - WhiteListIni:Erase() -- Empty entire loaded ini first, otherwise weird shit goes down - WhiteListIni:ReadFile() - UpdateMessage = "Loaded from disk" - elseif( Request.Params["whitelist-setenable"] ~= nil ) then - local Enabled = Request.Params["whitelist-setenable"] - local CreateNewValue = false - if( WhiteListIni:FindValue( WhiteListIni:FindKey("WhiteListSettings"), "WhiteListOn" ) == cIniFile.noID ) then -- Find out whether the value is in the ini - CreateNewValue = true - end - - if( Enabled == "1" ) then - WhiteListIni:SetValueB("WhiteListSettings", "WhiteListOn", true, CreateNewValue ) - else - WhiteListIni:SetValueB("WhiteListSettings", "WhiteListOn", false, CreateNewValue ) - end - WhiteListIni:WriteFile() - end - - - local Content = "" - - local WhiteListEnabled = WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false) - if( WhiteListEnabled == false ) then - Content = Content .. "

Whitelist is currently disabled! Click here to enable.

" - end - - - Content = Content .. "

Whitelisted players

" - Content = Content .. "" - local KeyNum = WhiteListIni:FindKey("WhiteList") - local NumValues = WhiteListIni:GetNumValues(KeyNum) - if( NumValues > 0 ) then - for Num = 0, NumValues-1 do - if( WhiteListIni:GetValue(KeyNum, Num, "0") == "1" ) then - local PlayerName = WhiteListIni:GetValueName(KeyNum, Num ) - Content = Content .. "" - end - end - else - Content = Content .. "" - end - Content = Content .. "
" .. PlayerName .. "" .. HTMLDeleteButton( PlayerName ) .. "
None
" - Content = Content .. "

Add player to whitelist

" - Content = Content .. "
" - Content = Content .. "" - Content = Content .. "
" - Content = Content .. "
" - Content = Content .. "" - Content = Content .. "
" - Content = Content .. "
"..UpdateMessage - - if( WhiteListEnabled == true ) then - Content = Content .. "

Whitelist is currently enabled, click here to disable.

" - end - - return Content -end \ No newline at end of file diff --git a/MCServer/Plugins/Core/worldlimiter.lua b/MCServer/Plugins/Core/worldlimiter.lua deleted file mode 100644 index 1bb1b4fc6..000000000 --- a/MCServer/Plugins/Core/worldlimiter.lua +++ /dev/null @@ -1,22 +0,0 @@ -function OnPlayerMoving( Player ) - LimitWorldWidth = WorldsWorldLimit[Player:GetWorld():GetName()] - if LimitWorldWidth > 0 then - local World = Player:GetWorld() - local SpawnX = math.floor(World:GetSpawnX() / 16) - local SpawnZ = math.floor(World:GetSpawnZ() / 16) - local X = math.floor(Player:GetPosX() / 16) - local Z = math.floor(Player:GetPosZ() / 16) - if ( (SpawnX + LimitWorldWidth - 1) < X ) then - Player:TeleportToCoords(Player:GetPosX() - 1, Player:GetPosY(), Player:GetPosZ()) - end - if ( (SpawnX - LimitWorldWidth + 1) > X ) then - Player:TeleportToCoords(Player:GetPosX() + 1, Player:GetPosY(), Player:GetPosZ()) - end - if ( (SpawnZ + LimitWorldWidth - 1) < Z ) then - Player:TeleportToCoords(Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() - 1) - end - if ( (SpawnZ - LimitWorldWidth + 1) > Z ) then - Player:TeleportToCoords(Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() + 1) - end - end -end \ No newline at end of file -- cgit v1.2.3 From 8326aff5b4c2b9e5ddc5b4c1c40fd791d7e8ef4b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 09:30:27 +0200 Subject: Added the ClonePlugins script. This will clone the base plugins into their respective folders. --- ClonePlugins.cmd | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ClonePlugins.cmd diff --git a/ClonePlugins.cmd b/ClonePlugins.cmd new file mode 100644 index 000000000..bf1dfa23a --- /dev/null +++ b/ClonePlugins.cmd @@ -0,0 +1,6 @@ + +:: ClonePlugins.cmd + +:: Clones the base plugins from their respective repos into proper folders (./MCServer/Plugins + +git clone https://github.com/mc-server/Core.git ./MCServer/Plugins/Core \ No newline at end of file -- cgit v1.2.3 From 0074432ccd64791382f0629c1e863ec20a78949d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 09:38:57 +0200 Subject: Moved ProtectionAreas into a separate repository --- ClonePlugins.cmd | 3 +- MCServer/Plugins/.gitignore | 3 +- .../Plugins/ProtectionAreas/CommandHandlers.lua | 322 ------------- MCServer/Plugins/ProtectionAreas/CommandState.lua | 121 ----- MCServer/Plugins/ProtectionAreas/Config.lua | 55 --- MCServer/Plugins/ProtectionAreas/CurrentLng.lua | 76 --- MCServer/Plugins/ProtectionAreas/HookHandlers.lua | 139 ------ MCServer/Plugins/ProtectionAreas/LICENSE.txt | 7 - MCServer/Plugins/ProtectionAreas/PlayerAreas.lua | 109 ----- .../Plugins/ProtectionAreas/ProtectionAreas.deproj | 27 -- .../Plugins/ProtectionAreas/ProtectionAreas.lua | 71 --- MCServer/Plugins/ProtectionAreas/Storage.lua | 518 --------------------- 12 files changed, 4 insertions(+), 1447 deletions(-) delete mode 100644 MCServer/Plugins/ProtectionAreas/CommandHandlers.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/CommandState.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/Config.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/CurrentLng.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/HookHandlers.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/LICENSE.txt delete mode 100644 MCServer/Plugins/ProtectionAreas/PlayerAreas.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/ProtectionAreas.deproj delete mode 100644 MCServer/Plugins/ProtectionAreas/ProtectionAreas.lua delete mode 100644 MCServer/Plugins/ProtectionAreas/Storage.lua diff --git a/ClonePlugins.cmd b/ClonePlugins.cmd index bf1dfa23a..ad1fbe014 100644 --- a/ClonePlugins.cmd +++ b/ClonePlugins.cmd @@ -3,4 +3,5 @@ :: Clones the base plugins from their respective repos into proper folders (./MCServer/Plugins -git clone https://github.com/mc-server/Core.git ./MCServer/Plugins/Core \ No newline at end of file +git clone https://github.com/mc-server/Core.git ./MCServer/Plugins/Core +git clone https://github.com/mc-server/ProtectionAreas.git ./MCServer/Plugins/ProtectionAreas \ No newline at end of file diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore index a9f9bd175..010351de2 100644 --- a/MCServer/Plugins/.gitignore +++ b/MCServer/Plugins/.gitignore @@ -1 +1,2 @@ -Core \ No newline at end of file +Core +ProtectionAreas \ No newline at end of file diff --git a/MCServer/Plugins/ProtectionAreas/CommandHandlers.lua b/MCServer/Plugins/ProtectionAreas/CommandHandlers.lua deleted file mode 100644 index 26df73075..000000000 --- a/MCServer/Plugins/ProtectionAreas/CommandHandlers.lua +++ /dev/null @@ -1,322 +0,0 @@ - --- CommandHandlers.lua --- Defines the individual command handlers - - - - - -function InitializeCommandHandlers() - local PlgMgr = cRoot:Get():GetPluginManager(); - for idx, Cmd in ipairs(CommandReg()) do - PlgMgr:BindCommand(Cmd[2], Cmd[3], Cmd[1], Cmd[4]); - end -end - - - - - ---- Handles the ProtAdd command -function HandleAddArea(a_Split, a_Player) - -- Command syntax: ProtAdd username1 [username2] [username3] ... - if (#a_Split < 2) then - a_Player:SendMessage(g_Msgs.ErrExpectedListOfUsernames); - return true; - end - - -- Get the cuboid that the player had selected - local CmdState = GetCommandStateForPlayer(a_Player); - if (CmdState == nil) then - a_Player:SendMessage(g_Msgs.ErrCmdStateNilAddArea); - return true; - end - local Cuboid = CmdState:GetCurrentCuboid(); - if (Cuboid == nil) then - a_Player:SendMessage(g_Msgs.ErrNoAreaWanded); - return true; - end - - -- Put all allowed players into a table: - AllowedNames = {}; - for i = 2, #a_Split do - table.insert(AllowedNames, a_Split[i]); - end - - -- Add the area to the storage - local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames); - a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID)); - - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - -function HandleAddAreaCoords(a_Split, a_Player) - -- Command syntax: ProtAddCoords x1 z1 x2 z2 username1 [username2] [username3] ... - if (#a_Split < 6) then - a_Player:SendMessage(g_Msgs.ErrExpectedCoordsUsernames); - return true; - end - - -- Convert the coords to a cCuboid - local x1, z1 = tonumber(a_Split[2]), tonumber(a_Split[3]); - local x2, z2 = tonumber(a_Split[4]), tonumber(a_Split[5]); - if ((x1 == nil) or (z1 == nil) or (x2 == nil) or (z2 == nil)) then - a_Player:SendMessage(g_Msgs.ErrParseCoords); - return true; - end - local Cuboid = cCuboid(x1, 0, z1, x2, 255, z1); - Cuboid:Sort(); - - -- Put all allowed players into a table: - AllowedNames = {}; - for i = 6, #a_Split do - table.insert(AllowedNames, a_Split[i]); - end - - -- Add the area to the storage - local AreaID = g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames); - a_Player:SendMessage(string.format(g_Msgs.AreaAdded, AreaID)); - - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - -function HandleAddAreaUser(a_Split, a_Player) - -- Command syntax: ProtAddUser AreaID username1 [username2] [username3] ... - if (#a_Split < 3) then - a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUsernames); - return true; - end - - -- Put all allowed players into a table: - AllowedNames = {}; - for i = 3, #a_Split do - table.insert(AllowedNames, a_Split[i]); - end - - -- Add the area to the storage - if (not(g_Storage:AddAreaUsers( - tonumber(a_Split[2]), a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames)) - ) then - LOGWARNING("g_Storage:AddAreaUsers failed"); - a_Player:SendMessage(g_Msgs.ErrDBFailAddUsers); - return true; - end - if (#AllowedNames == 0) then - a_Player:SendMessage(g_Msgs.AllUsersAlreadyAllowed); - else - a_Player:SendMessage(string.format(g_Msgs.UsersAdded, table.concat(AllowedNames, ", "))); - end - - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - -function HandleDelArea(a_Split, a_Player) - -- Command syntax: ProtDelArea AreaID - if (#a_Split ~= 2) then - a_Player:SendMessage(g_Msgs.ErrExpectedAreaID); - return true; - end - - -- Parse the AreaID - local AreaID = tonumber(a_Split[2]); - if (AreaID == nil) then - a_Player:SendMessage(g_Msgs.ErrParseAreaID); - return true; - end - - -- Delete the area - g_Storage:DelArea(a_Player:GetWorld():GetName(), AreaID); - - a_Player:SendMessage(string.format(g_Msgs.AreaDeleted, AreaID)); - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - -function HandleGiveWand(a_Split, a_Player) - local NumGiven = a_Player:GetInventory():AddItem(cConfig:GetWandItem()); - if (NumGiven == 1) then - a_Player:SendMessage(g_Msgs.WandGiven); - else - a_Player:SendMessage(g_Msgs.ErrNoSpaceForWand); - end - return true; -end - - - - - -function HandleListAreas(a_Split, a_Player) - -- Command syntax: ProtListAreas [x, z] - - local x, z; - if (#a_Split == 1) then - -- Get the last "wanded" coord - local CmdState = GetCommandStateForPlayer(a_Player); - if (CmdState == nil) then - a_Player:SendMessage(g_Msgs.ErrCmdStateNilListAreas); - return true; - end - x, z = CmdState:GetLastCoords(); - if ((x == nil) or (z == nil)) then - a_Player:SendMessage(g_Msgs.ErrListNotWanded); - return true; - end - elseif (#a_Split == 3) then - -- Parse the coords from the command params - x = tonumber(a_Split[2]); - z = tonumber(a_Split[3]); - if ((x == nil) or (z == nil)) then - a_Player:SendMessage(g_Msgs.ErrParseCoordsListAreas); - return true; - end - else - -- Wrong number of params, report back to the user - a_Player:SendMessage(g_Msgs.ErrSyntaxErrorListAreas); - return true; - end - - a_Player:SendMessage(string.format(g_Msgs.ListAreasHeader, x, z)); - - -- List areas intersecting the coords - local PlayerName = a_Player:GetName(); - local WorldName = a_Player:GetWorld():GetName(); - g_Storage:ForEachArea(x, z, WorldName, - function(AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName) - local Coords = string.format("%s: {%d, %d} - {%d, %d} ", AreaID, MinX, MinZ, MaxX, MaxZ); - local Allowance; - if (g_Storage:IsAreaAllowed(AreaID, PlayerName, WorldName)) then - Allowance = g_Msgs.AreaAllowed; - else - Allowance = g_Msgs.AreaNotAllowed; - end - a_Player:SendMessage(string.format(g_Msgs.ListAreasRow, Coords, Allowance, CreatorName)); - end - ); - - a_Player:SendMessage(g_Msgs.ListAreasFooter); - return true; -end - - - - ---- Lists all allowed users for a particular area -function HandleListUsers(a_Split, a_Player) - -- Command syntax: ProtListUsers AreaID - if (#a_Split ~= 2) then - a_Player:SendMessage(g_Msgs.ErrExpectedAreaID); - end - - -- Get the general info about the area - local AreaID = a_Split[2]; - local WorldName = a_Player:GetWorld():GetName(); - local MinX, MinZ, MaxX, MaxZ, CreatorName = g_Storage:GetArea(AreaID, WorldName); - if (MinX == nil) then - a_Player:SendMessage(string.format(g_Msgs.ErrNoSuchArea, AreaID)); - return true; - end - - -- Send the header - a_Player:SendMessage(string.format(g_Msgs.ListUsersHeader, AreaID, MinX, MinZ, MaxX, MaxZ, CreatorName)); - - -- List and count the allowed users - local NumUsers = 0; - g_Storage:ForEachUserInArea(AreaID, WorldName, - function(UserName) - a_Player:SendMessage(string.format(g_Msgs.ListUsersRow, UserName)); - NumUsers = NumUsers + 1; - end - ); - - -- Send the footer - a_Player:SendMessage(string.format(g_Msgs.ListUsersFooter, AreaID, NumUsers)); - - return true; -end - - - - - -function HandleRemoveUser(a_Split, a_Player) - -- Command syntax: ProtRemUser AreaID UserName - if (#a_Split ~= 3) then - a_Player:SendMessage(g_Msgs.ErrExpectedAreaIDUserName); - return true; - end - - -- Parse the AreaID - local AreaID = tonumber(a_Split[2]); - if (AreaID == nil) then - a_Player:SendMessage(g_Msgs.ErrParseAreaID); - return true; - end - - -- Remove the user from the DB - local UserName = a_Split[3]; - g_Storage:RemoveUser(AreaID, UserName, a_Player:GetWorld():GetName()); - - -- Send confirmation - a_Player:SendMessage(string.format(g_Msgs.RemovedUser, UserName, AreaID)); - - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - -function HandleRemoveUserAll(a_Split, a_Player) - -- Command syntax: ProtRemUserAll UserName - if (#a_Split ~= 2) then - a_Player:SendMessage(g_Msgs.ErrExpectedUserName); - return true; - end - - -- Remove the user from the DB - g_Storage:RemoveUserAll(a_Split[2], a_Player:GetWorld():GetName()); - - -- Send confirmation - a_Player:SendMessage(string.format(g_Msgs.RemovedUserAll, UserName)); - - -- Reload all currently logged in players - ReloadAllPlayersInWorld(a_Player:GetWorld():GetName()); - - return true; -end - - - - - diff --git a/MCServer/Plugins/ProtectionAreas/CommandState.lua b/MCServer/Plugins/ProtectionAreas/CommandState.lua deleted file mode 100644 index f6d33d356..000000000 --- a/MCServer/Plugins/ProtectionAreas/CommandState.lua +++ /dev/null @@ -1,121 +0,0 @@ - --- CommandState.lua - --- Implements the cCommandState class representing a command state for each VIP player - ---[[ -The command state holds internal info, such as the coords they selected using the wand -The command state needs to be held in a per-entity manner, so that we can support multiple logins -from the same account (just for the fun of it) -The OOP class implementation follows the PiL 16.1 - -Also, a global table g_CommandStates is the map of PlayerEntityID -> cCommandState ---]] - - - - - -cCommandState = { - -- Default coords - m_Coords1 = {x = 0, z = 0}; -- lclk coords - m_Coords2 = {x = 0, z = 0}; -- rclk coords - m_LastCoords = 0; -- When Coords1 or Coords2 is set, this gets set to 1 or 2, signifying the last changed set of coords - m_HasCoords1 = false; -- Set to true when m_Coords1 has been set by the user - m_HasCoords2 = false; -- Set to true when m_Coords2 has been set by the user -}; - -g_CommandStates = {}; - - - - - -function cCommandState:new(obj) - obj = obj or {}; - setmetatable(obj, self); - self.__index = self; - return obj; -end - - - - - ---- Returns the current coord pair as a cCuboid object -function cCommandState:GetCurrentCuboid() - if (not(self.m_HasCoords1) or not(self.m_HasCoords2)) then - -- Some of the coords haven't been set yet - return nil; - end - - local res = cCuboid( - self.m_Coords1.x, 0, self.m_Coords1.z, - self.m_Coords2.x, 255, self.m_Coords2.z - ); - res:Sort(); - return res; -end - - - - - ---- Returns the x, z coords that were the set last, --- That is, either m_Coords1 or m_Coords2, based on m_LastCoords member --- Returns nothing if no coords were set yet -function cCommandState:GetLastCoords() - if (self.m_LastCoords == 0) then - -- No coords have been set yet - return; - elseif (self.m_LastCoords == 1) then - return self.m_Coords1.x, self.m_Coords1.z; - elseif (self.m_LastCoords == 2) then - return self.m_Coords2.x, self.m_Coords2.z; - else - LOGWARNING(PluginPrefix .. "cCommandState is in an unexpected state, m_LastCoords == " .. self.m_LastCoords); - return; - end -end - - - - - ---- Sets the first set of coords (upon rclk with a wand) -function cCommandState:SetCoords1(a_BlockX, a_BlockZ) - self.m_Coords1.x = a_BlockX; - self.m_Coords1.z = a_BlockZ; - self.m_LastCoords = 1; - self.m_HasCoords1 = true; -end - - - - - ---- Sets the second set of coords (upon lclk with a wand) -function cCommandState:SetCoords2(a_BlockX, a_BlockZ) - self.m_Coords2.x = a_BlockX; - self.m_Coords2.z = a_BlockZ; - self.m_LastCoords = 2; - self.m_HasCoords2 = true; -end - - - - - ---- Returns the cCommandState for the specified player; creates one if not existant -function GetCommandStateForPlayer(a_Player) - local res = g_CommandStates[a_Player:GetUniqueID()]; - if (res == nil) then - res = cCommandState:new(); - g_CommandStates[a_Player:GetUniqueID()] = res; - end - return res; -end; - - - - diff --git a/MCServer/Plugins/ProtectionAreas/Config.lua b/MCServer/Plugins/ProtectionAreas/Config.lua deleted file mode 100644 index b40be0c75..000000000 --- a/MCServer/Plugins/ProtectionAreas/Config.lua +++ /dev/null @@ -1,55 +0,0 @@ - --- Config.lua - --- Implements the cConfig class that holds the general plugin configuration - - - - - -cConfig = { - m_Wand = cItem(E_ITEM_STICK, 1, 1); -- The item to be used as the selection wand - m_AllowInteractNoArea = true; -- If there's no area, is a player allowed to build / dig? -}; - - - - - ---- Initializes the cConfig object, loads the configuration from an INI file -function InitializeConfig() - local ini = cIniFile("ProtectionAreas.ini"); - if (not(ini:ReadFile())) then - LOGINFO(PluginPrefix .. "Cannot read ProtectionAreas.ini, all plugin configuration is set to defaults"); - end - local WandItem = cItem(); - if ( - StringToItem(ini:GetValueSet("ProtectionAreas", "WandItem", ItemToString(cConfig.m_Wand)), WandItem) and - IsValidItem(WandItem.m_ItemType) - ) then - cConfig.m_Wand = WandItem; - end - cConfig.m_AllowInteractNoArea = ini:GetValueSetB("ProtectionAreas", "AllowInteractNoArea", cConfig.m_AllowInteractNoArea); - ini:WriteFile(); -end - - - - - ---- Returns true if a_Item is the wand tool item -function cConfig:IsWand(a_Item) - return ( - (a_Item.m_ItemType == self.m_Wand.m_ItemType) and - (a_Item.m_ItemDamage == self.m_Wand.m_ItemDamage) - ); -end - - - - - ---- Returns the wand tool item as a cItem object -function cConfig:GetWandItem() - return self.m_Wand; -end \ No newline at end of file diff --git a/MCServer/Plugins/ProtectionAreas/CurrentLng.lua b/MCServer/Plugins/ProtectionAreas/CurrentLng.lua deleted file mode 100644 index 37ff135c5..000000000 --- a/MCServer/Plugins/ProtectionAreas/CurrentLng.lua +++ /dev/null @@ -1,76 +0,0 @@ - --- CurrentLng.lua --- This file provides all the translatable strings --- The expectation is that the translators will create copies of this file, translate the texts and then the users will overwrite this file with a specific language version --- Note that the individual languages must not have ".lua" extension, otherwise MCServer will load them and the plugin won't work! - - - - --- Individual commands, and their help strings. Don't touch the first symbol on each line! --- This needs to be implemented as a function, because it references other functions which might not yet be loaded while Lua is processing the globals - -function CommandReg() - return { - -- Handler function | Command | Permission | Help text - {HandleAddArea, "/ProtAdd", "Prot.Add", " - Adds a new protected area"}, - {HandleAddAreaCoords, "/ProtAddCoords", "Prot.Add", " - Adds a new protected area by coords"}, - {HandleAddAreaUser, "/ProtAddUser", "Prot.AddUser", " - Adds new users to an existing protected area"}, - {HandleDelArea, "/ProtDelID", "Prot.Del", " - Deletes a protected area by ID"}, - {HandleGiveWand, "/ProtWand", "Prot.Wand", " - Gives you the wand used for protection"}, - {HandleListAreas, "/ProtList", "Prot.List", "[ ] - Lists all areas for the marked block or given coords"}, - {HandleListUsers, "/ProtUsers", "Prot.List", " - Lists all allowed users for a given area ID"}, - {HandleRemoveUser, "/ProtRemUser", "Prot.RemUser", " - Removes a user from the protected area"}, - {HandleRemoveUserAll, "/ProtRemUserAll", "Prot.RemUser", " - Removes a user from all protected areas"}, - }; -end; - - - - - ---- Messages sent to players -g_Msgs = -{ - AllUsersAlreadyAllowed = "All the specified users were already allowed."; - AreaAdded = "Area added, ID %s"; - AreaAllowed = "Allowed"; - AreaDeleted = "Area ID %s deleted"; - AreaNotAllowed = "NOT allowed"; - Coords1Set = "Coords1 set as {%d, %d}"; - Coords2Set = "Coords2 set as {%d, %d}"; - ErrCmdStateNilAddArea = "Cannot add area, internal plugin error (CmdState == nil)"; - ErrCmdStateNilListAreas = "Cannot list areas, internal plugin error (CmdState == nil)"; - ErrDBFailAddUsers = "Cannot add users, DB failure"; - ErrExpectedAreaID = "Parameter mismatch. Expected ."; - ErrExpectedAreaIDUserName = "Parameter mismatch. Expected ."; - ErrExpectedAreaIDUsernames = "Not enough parameters. Expected and a list of usernames."; - ErrExpectedCoordsUsernames = "Not enough parameters. Expected coords and a list of usernames."; - ErrExpectedListOfUsernames = "Not enough parameters. Expected a list of usernames."; - ErrExpectedUserName = "Parameter mismatch. Expected ."; - ErrListNotWanded = "Cannot list areas, no query point has been selected. Use a ProtWand lclk / rclk to select a point first"; - ErrNoAreaWanded = "Cannot add area, no area has been selected. Use a ProtWand lclk / rclk to select area first"; - ErrNoSpaceForWand = "Cannot give wand, no space in your inventory"; - ErrNoSuchArea = "No such area: %s"; - ErrParseAreaID = "Cannot parse ."; - ErrParseCoords = "Cannot parse coords."; - ErrParseCoordsListAreas = "Cannot list areas, cannot parse coords in params"; - ErrSyntaxErrorListAreas = "Cannot list areas, syntax error. Expected either no params or ."; - ListAreasFooter = "Area list finished"; - ListAreasHeader = "Listing protection areas intersecting block column {%d, %d}:"; - ListAreasRow = " %s, %s, created by %s"; - ListUsersFooter = "End of area %s user list, total %d users"; - ListUsersHeader = "Area ID %s: {%d, %d} - {%d, %d}, created by %s; allowed users:"; - ListUsersRow = " %s"; - NotAllowedToBuild = "You are not allowed to build here!"; - NotAllowedToDig = "You are not allowed to dig here!"; - RemovedUser = "Removed %s from area %d"; - RemovedUserAll = "Removed %s from all areas"; - UsersAdded = "Users added: %s"; - WandGiven = "Wand given"; -} ; - - - - - diff --git a/MCServer/Plugins/ProtectionAreas/HookHandlers.lua b/MCServer/Plugins/ProtectionAreas/HookHandlers.lua deleted file mode 100644 index ded64d298..000000000 --- a/MCServer/Plugins/ProtectionAreas/HookHandlers.lua +++ /dev/null @@ -1,139 +0,0 @@ - --- HookHandlers.lua --- Implements the handlers for individual hooks - - - - - ---- Registers all the hooks that the plugin needs to know about -function InitializeHooks(a_Plugin) - local PlgMgr = cRoot:Get():GetPluginManager(); - PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_DISCONNECT); - PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_LEFT_CLICK); - PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_MOVING); - PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_RIGHT_CLICK); - PlgMgr:AddHook(a_Plugin, cPluginManager.HOOK_PLAYER_SPAWNED); -end - - - - - ---- Called by MCS when a player's connectino is lost - either they disconnected or timed out -function OnDisconnect(a_Player, a_Reason) - -- Remove the player's cProtectionArea object - g_PlayerAreas[a_Player:GetUniqueID()] = nil; - - -- If the player is a VIP, they had a command state, remove that as well - g_CommandStates[a_Player:GetUniqueID()] = nil; - - return false; -end; - - - - - ---- Called by MCS whenever a player enters a world (is spawned) -function OnPlayerSpawned(a_Player) - -- Create a new cPlayerAreas object for this player - if (g_PlayerAreas[a_Player:GetUniqueID()] == nil) then - LoadPlayerAreas(a_Player); - end; - - return false; -end - - - - - ---- Called by MCS whenever a player is moving (at most once every tick) -function OnPlayerMoving(a_Player) - local PlayerID = a_Player:GetUniqueID(); - - -- If for some reason we don't have a cPlayerAreas object for this player, load it up - local PlayerAreas = g_PlayerAreas[PlayerID]; - if (PlayerAreas == nil) then - LoadPlayerAreas(a_Player); - return false; - end; - - -- If the player is outside their areas' safe space, reload - if (not(PlayerAreas:IsInSafe(a_Player:GetPosX(), a_Player:GetPosZ()))) then - LoadPlayerAreas(a_Player); - end - return false; -end - - - - - ---- Called by MCS when a player left-clicks -function OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status) - -- If the player has lclked with the wand; regardless of their permissions, let's set the coords: - if (cConfig:IsWand(a_Player:GetEquippedItem())) then - -- BlockFace < 0 means "use item", for which the coords are not given by the client - if (a_BlockFace < 0) then - return true; - end - - -- Convert the clicked coords into the block space - a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - - -- Set the coords in the CommandState - GetCommandStateForPlayer(a_Player):SetCoords1(a_BlockX, a_BlockZ); - a_Player:SendMessage(string.format(g_Msgs.Coords1Set, a_BlockX, a_BlockZ)); - return true; - end; - - -- Check the player areas to see whether to disable this action - local Areas = g_PlayerAreas[a_Player:GetUniqueID()]; - if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then - a_Player:SendMessage(g_Msgs.NotAllowedToDig); - return true; - end - - -- Allow interaction - return false; -end - - - - - ---- Called by MCS when a player right-clicks -function OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_Status) - - -- BlockFace < 0 means "use item", for which the coords are not given by the client - if (a_BlockFace < 0) then - return true; - end - - -- Convert the clicked coords into the block space - a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - - -- If the player has rclked with the wand; regardless of their permissions, let's set the coords - if (cConfig:IsWand(a_Player:GetEquippedItem())) then - -- Set the coords in the CommandState - GetCommandStateForPlayer(a_Player):SetCoords2(a_BlockX, a_BlockZ); - a_Player:SendMessage(string.format(g_Msgs.Coords2Set, a_BlockX, a_BlockZ)); - return true; - end; - - -- Check the player areas to see whether to disable this action - local Areas = g_PlayerAreas[a_Player:GetUniqueID()]; - if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then - a_Player:SendMessage(g_Msgs.NotAllowedToBuild); - return true; - end - - -- Allow interaction - return false; -end - - - - diff --git a/MCServer/Plugins/ProtectionAreas/LICENSE.txt b/MCServer/Plugins/ProtectionAreas/LICENSE.txt deleted file mode 100644 index 86c9130cc..000000000 --- a/MCServer/Plugins/ProtectionAreas/LICENSE.txt +++ /dev/null @@ -1,7 +0,0 @@ - -ProtectionAreas license -======================= - -The ProtectionAreas plugin is written by _Xoft(o) / Mattes and is hereby released as public domain. - -If you like it, I'd really appreciate a postcard, or something tiny typical from your country :) The current snailmail address is at my personal web, http://xoft.cz . diff --git a/MCServer/Plugins/ProtectionAreas/PlayerAreas.lua b/MCServer/Plugins/ProtectionAreas/PlayerAreas.lua deleted file mode 100644 index f6106ee77..000000000 --- a/MCServer/Plugins/ProtectionAreas/PlayerAreas.lua +++ /dev/null @@ -1,109 +0,0 @@ - --- PlayerAreas.lua --- Implements the cPlayerAreas class representing the per-player area storage object - ---[[ -Each player instance is expected to have a separate object of type cPlayerAreas. -Each object has an array of {cuboid, IsAllowed} tables, one for each area that is "within reach" -The code can then ask each object, whether the player can interact with a certain block or not. -A player can interact with a block if either one of these is true: -1, There are no areas covering the block -2, There is at least one area covering the block with IsAllowed set to true -The object also has a m_SafeCuboid object that specified the area within which the player may move -without the PlayerAreas needing a re-query. - -Also, a global table g_PlayerAreas is the actual map of PlayerID -> cPlayerAreas ---]] - - - - -cPlayerAreas = {}; - -g_PlayerAreas = {}; - - - - - -function cPlayerAreas:new(a_SafeMinX, a_SafeMinZ, a_SafeMaxX, a_SafeMaxZ) - assert(a_SafeMinX); - assert(a_SafeMinZ); - assert(a_SafeMaxX); - assert(a_SafeMaxZ); - - local obj = {}; - setmetatable(obj, self); - self.__index = self; - self.m_SafeCuboid = cCuboid(a_SafeMinX, 0, a_SafeMinZ, a_SafeMaxX, 255, a_SafeMaxZ); - return obj; -end - - - - --- Adds a new cuboid to the area list, where the player is either allowed or not, depending on the IsAllowed param -function cPlayerAreas:AddArea(a_Cuboid, a_IsAllowed) - table.insert(self, {m_Cuboid = a_Cuboid, m_IsAllowed = a_IsAllowed}); -end - - - - - ---- returns true if the player owning this object can interact with the specified block -function cPlayerAreas:CanInteractWithBlock(a_BlockX, a_BlockZ) - assert(self); - - -- iterate through all the stored areas: - local IsInsideAnyArea = false; - for idx, Area in ipairs(self) do - if (Area.m_Cuboid:IsInside(a_BlockX, 1, a_BlockZ)) then -- We don't care about Y coords, so use a dummy value - if (Area.m_IsAllowed) then - return true; - end - -- The coords are inside a cuboid for which the player doesn't have access, take a note of it - IsInsideAnyArea = true; - end - end - - if (IsInsideAnyArea) then - -- The specified coords are inside at least one area, but none of them allow the player to interact - return false; - end - - -- The coords are not inside any area - return cConfig.m_AllowInteractNoArea; -end - - - - - ---- Calls the specified callback for each area contained within --- a_Callback has a signature: function(a_Cuboid, a_IsAllowed) --- Returns true if all areas have been enumerated, false if the callback has aborted by returning true -function cPlayerAreas:ForEachArea(a_Callback) - assert(self); - - for idx, Area in ipairs(self) do - if (a_Callback(Area.m_Cuboid, Area.m_IsAllowed)) then - return false; - end - end - return true; -end - - - - - ---- Returns true if the player is withing the safe cuboid (no need to re-query the areas) -function cPlayerAreas:IsInSafe(a_BlockX, a_BlockZ) - assert(self); - return self.m_SafeCuboid:IsInside(a_BlockX, 0, a_BlockZ); -end - - - - diff --git a/MCServer/Plugins/ProtectionAreas/ProtectionAreas.deproj b/MCServer/Plugins/ProtectionAreas/ProtectionAreas.deproj deleted file mode 100644 index d1a2188f7..000000000 --- a/MCServer/Plugins/ProtectionAreas/ProtectionAreas.deproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - CommandHandlers.lua - - - CommandState.lua - - - Config.lua - - - CurrentLng.lua - - - HookHandlers.lua - - - PlayerAreas.lua - - - ProtectionAreas.lua - - - Storage.lua - - diff --git a/MCServer/Plugins/ProtectionAreas/ProtectionAreas.lua b/MCServer/Plugins/ProtectionAreas/ProtectionAreas.lua deleted file mode 100644 index cbe3fa94d..000000000 --- a/MCServer/Plugins/ProtectionAreas/ProtectionAreas.lua +++ /dev/null @@ -1,71 +0,0 @@ - --- ProtectionAreas.lua --- Defines the main plugin entrypoint, as well as some utility functions - - - - - ---- Prefix for all messages logged to the server console -PluginPrefix = "ProtectionAreas: "; - ---- Bounds for the area loading. Areas less this far in any direction from the player will be loaded into cPlayerAreas -g_AreaBounds = 48; - ---- If a player moves this close to the PlayerAreas bounds, the PlayerAreas will be re-queried -g_AreaSafeEdge = 12; - - - - - ---- Called by MCS when the plugin loads --- Returns true if initialization successful, false otherwise -function Initialize(a_Plugin) - a_Plugin:SetName("ProtectionAreas"); - a_Plugin:SetVersion(1); - - InitializeConfig(); - if (not(InitializeStorage())) then - LOGWARNING(PluginPrefix .. "failed to initialize Storage, plugin is disabled"); - return false; - end - InitializeHooks(a_Plugin); - InitializeCommandHandlers(); - - -- We might be reloading, so there may be players already present in the server; reload all of them - cRoot:Get():ForEachWorld( - function(a_World) - ReloadAllPlayersInWorld(a_World:GetName()); - end - ); - - return true; -end - - - - - ---- Loads a cPlayerAreas object from the DB for the player, and assigns it to the player map -function LoadPlayerAreas(a_Player) - local PlayerID = a_Player:GetUniqueID(); - local PlayerX = math.floor(a_Player:GetPosX()); - local PlayerZ = math.floor(a_Player:GetPosZ()); - local WorldName = a_Player:GetWorld():GetName(); - g_PlayerAreas[PlayerID] = g_Storage:LoadPlayerAreas(a_Player:GetName(), PlayerX, PlayerZ, WorldName); -end - - - - - -function ReloadAllPlayersInWorld(a_WorldName) - local World = cRoot:Get():GetWorld(a_WorldName); - World:ForEachPlayer(LoadPlayerAreas); -end - - - - - diff --git a/MCServer/Plugins/ProtectionAreas/Storage.lua b/MCServer/Plugins/ProtectionAreas/Storage.lua deleted file mode 100644 index a6cf564bf..000000000 --- a/MCServer/Plugins/ProtectionAreas/Storage.lua +++ /dev/null @@ -1,518 +0,0 @@ - --- Storage.lua --- Implements the storage access object, shielding the rest of the code away from the DB - ---[[ -The cStorage class is the interface to the underlying storage, the SQLite database. -This class knows how to load player areas from the DB, how to add or remove areas in the DB -and other such operations. - -Also, a g_Storage global variable is declared, it holds the single instance of the storage. ---]] - - - - - -cStorage = {}; - -g_Storage = {}; - - - - - ---- Initializes the storage subsystem, creates the g_Storage object --- Returns true if successful, false if not -function InitializeStorage() - g_Storage = cStorage:new(); - if (not(g_Storage:OpenDB())) then - return false; - end - - return true; -end - - - - - -function cStorage:new(obj) - obj = obj or {}; - setmetatable(obj, self); - self.__index = self; - return obj; -end - - - - ---- Opens the DB and makes sure it has all the columns needed --- Returns true if successful, false otherwise -function cStorage:OpenDB() - local ErrCode, ErrMsg; - self.DB, ErrCode, ErrMsg = sqlite3.open("ProtectionAreas.sqlite"); - if (self.DB == nil) then - LOGWARNING(PluginPrefix .. "Cannot open ProtectionAreas.sqlite, error " .. ErrCode .. " (" .. ErrMsg ..")"); - return false; - end - - if ( - not(self:CreateTable("Areas", {"ID INTEGER PRIMARY KEY AUTOINCREMENT", "MinX", "MaxX", "MinZ", "MaxZ", "WorldName", "CreatorUserName"})) or - not(self:CreateTable("AllowedUsers", {"AreaID", "UserName"})) - ) then - LOGWARNING(PluginPrefix .. "Cannot create DB tables!"); - return false; - end - - return true; -end - - - - - ---- Executes the SQL command given, calling the a_Callback for each result --- If the SQL command fails, prints it out on the server console and returns false --- Returns true on success -function cStorage:DBExec(a_SQL, a_Callback, a_CallbackParam) - local ErrCode = self.DB:exec(a_SQL, a_Callback, a_CallbackParam); - if (ErrCode ~= sqlite3.OK) then - LOGWARNING(PluginPrefix .. "Error " .. ErrCode .. " (" .. self.DB:errmsg() .. - ") while processing SQL command >>" .. a_SQL .. "<<" - ); - return false; - end - return true; -end - - - - - ---- Creates the table of the specified name and columns[] --- If the table exists, any columns missing are added; existing data is kept -function cStorage:CreateTable(a_TableName, a_Columns) - -- Try to create the table first - local sql = "CREATE TABLE IF NOT EXISTS '" .. a_TableName .. "' ("; - sql = sql .. table.concat(a_Columns, ", "); - sql = sql .. ")"; - if (not(self:DBExec(sql))) then - LOGWARNING(PluginPrefix .. "Cannot create DB Table " .. a_TableName); - return false; - end - -- SQLite doesn't inform us if it created the table or not, so we have to continue anyway - - -- Check each column whether it exists - -- Remove all the existing columns from a_Columns: - local RemoveExistingColumn = function(UserData, NumCols, Values, Names) - -- Remove the received column from a_Columns. Search for column name in the Names[] / Values[] pairs - for i = 1, NumCols do - if (Names[i] == "name") then - local ColumnName = Values[i]:lower(); - -- Search the a_Columns if they have that column: - for j = 1, #a_Columns do - -- Cut away all column specifiers (after the first space), if any: - local SpaceIdx = string.find(a_Columns[j], " "); - if (SpaceIdx ~= nil) then - SpaceIdx = SpaceIdx - 1; - end - local ColumnTemplate = string.lower(string.sub(a_Columns[j], 1, SpaceIdx)); - -- If it is a match, remove from a_Columns: - if (ColumnTemplate == ColumnName) then - table.remove(a_Columns, j); - break; -- for j - end - end -- for j - a_Columns[] - end - end -- for i - Names[] / Values[] - return 0; - end - if (not(self:DBExec("PRAGMA table_info(" .. a_TableName .. ")", RemoveExistingColumn))) then - LOGWARNING(PluginPrefix .. "Cannot query DB table structure"); - return false; - end - - -- Create the missing columns - -- a_Columns now contains only those columns that are missing in the DB - if (#a_Columns > 0) then - LOGINFO(PluginPrefix .. "Database table \"" .. a_TableName .. "\" is missing " .. #a_Columns .. " columns, fixing now."); - for idx, ColumnName in ipairs(a_Columns) do - if (not(self:DBExec("ALTER TABLE '" .. a_TableName .. "' ADD COLUMN " .. ColumnName))) then - LOGWARNING(PluginPrefix .. "Cannot add DB table \"" .. a_TableName .. "\" column \"" .. ColumnName .. "\""); - return false; - end - end - LOGINFO(PluginPrefix .. "Database table \"" .. a_TableName .. "\" columns fixed."); - end - - return true; -end - - - - - ---- Returns true if the specified area is allowed for the specified player -function cStorage:IsAreaAllowed(a_AreaID, a_PlayerName, a_WorldName) - assert(a_AreaID); - assert(a_PlayerName); - assert(a_WorldName); - assert(self); - - local lcPlayerName = string.lower(a_PlayerName); - local res = false; - local sql = "SELECT COUNT(*) FROM AllowedUsers WHERE (AreaID = " .. a_AreaID .. - ") AND (UserName ='" .. lcPlayerName .. "')"; - local function SetResTrue(UserData, NumValues, Values, Names) - res = (tonumber(Values[1]) > 0); - return 0; - end - if (not(self:DBExec(sql, SetResTrue))) then - LOGWARNING("SQL error while determining area allowance"); - return false; - end - return res; -end - - - - - ---- Loads cPlayerAreas for the specified player from the DB. Returns a cPlayerAreas object -function cStorage:LoadPlayerAreas(a_PlayerName, a_PlayerX, a_PlayerZ, a_WorldName) - assert(a_PlayerName); - assert(a_PlayerX); - assert(a_PlayerZ); - assert(a_WorldName); - assert(self); - - -- Bounds for which the areas are loaded - local BoundsMinX = a_PlayerX - g_AreaBounds; - local BoundsMaxX = a_PlayerX + g_AreaBounds; - local BoundsMinZ = a_PlayerZ - g_AreaBounds; - local BoundsMaxZ = a_PlayerZ + g_AreaBounds; - - local res = cPlayerAreas:new( - BoundsMinX + g_AreaSafeEdge, BoundsMinZ + g_AreaSafeEdge, - BoundsMaxX - g_AreaSafeEdge, BoundsMaxZ - g_AreaSafeEdge - ); - - --[[ - LOG("Loading protection areas for player " .. a_PlayerName .. " centered around {" .. a_PlayerX .. ", " .. a_PlayerZ .. - "}, bounds are {" .. BoundsMinX .. ", " .. BoundsMinZ .. "} - {" .. - BoundsMaxX .. ", " .. BoundsMaxZ .. "}" - ); - --]] - - -- Load the areas from the DB, based on the player's location - local lcWorldName = string.lower(a_WorldName); - local sql = - "SELECT ID, MinX, MaxX, MinZ, MaxZ FROM Areas WHERE " .. - "MinX < " .. BoundsMaxX .. " AND MaxX > " .. BoundsMinX .. " AND " .. - "MinZ < " .. BoundsMaxZ .. " AND MaxZ > " .. BoundsMinZ .. " AND " .. - "WorldName = '" .. lcWorldName .."'"; - - local function AddAreas(UserData, NumValues, Values, Names) - if ((NumValues < 5) or ((Values[1] and Values[2] and Values[3] and Values[4] and Values[5]) == nil)) then - LOGWARNING("SQL query didn't return all data"); - return 0; - end - res:AddArea(cCuboid(Values[2], 0, Values[4], Values[3], 255, Values[5]), self:IsAreaAllowed(Values[1], a_PlayerName, a_WorldName)); - return 0; - end - - if (not(self:DBExec(sql, AddAreas))) then - LOGWARNING("SQL error while querying areas"); - return res; - end - - return res; -end - - - - - ---- Adds a new area into the DB. a_AllowedNames is a table listing all the players that are allowed in the area --- Returns the ID of the new area, or -1 on failure -function cStorage:AddArea(a_Cuboid, a_WorldName, a_CreatorName, a_AllowedNames) - assert(a_Cuboid); - assert(a_WorldName); - assert(a_CreatorName); - assert(a_AllowedNames); - assert(self); - - -- Store the area in the DB - local ID = -1; - local function RememberID(UserData, NumCols, Values, Names) - for i = 1, NumCols do - if (Names[i] == "ID") then - ID = Values[i]; - end - end - return 0; - end - local lcWorldName = string.lower(a_WorldName); - local lcCreatorName = string.lower(a_CreatorName); - local sql = - "INSERT INTO Areas (ID, MinX, MaxX, MinZ, MaxZ, WorldName, CreatorUserName) VALUES (NULL, " .. - a_Cuboid.p1.x .. ", " .. a_Cuboid.p2.x .. ", " .. a_Cuboid.p1.z .. ", " .. a_Cuboid.p2.z .. - ", '" .. lcWorldName .. "', '" .. lcCreatorName .. - "'); SELECT last_insert_rowid() AS ID"; - if (not(self:DBExec(sql, RememberID))) then - LOGWARNING(PluginPrefix .. "SQL Error while inserting new area"); - return -1; - end - if (ID == -1) then - LOGWARNING(PluginPrefix .. "SQL Error while retrieving INSERTion ID"); - return -1; - end - - -- Store each allowed player in the DB - for idx, Name in ipairs(a_AllowedNames) do - local lcName = string.lower(Name); - local sql = "INSERT INTO AllowedUsers (AreaID, UserName) VALUES (" .. ID .. ", '" .. lcName .. "')"; - if (not(self:DBExec(sql))) then - LOGWARNING(PluginPrefix .. "SQL Error while inserting new area's allowed player " .. Name); - end - end - return ID; -end - - - - - -function cStorage:DelArea(a_WorldName, a_AreaID) - assert(a_WorldName); - assert(a_AreaID); - assert(self); - - -- Since all areas are stored in a single DB (for now), the worldname parameter isn't used at all - -- Later if we change to a per-world DB, we'll need the world name - - -- Delete from both tables simultaneously - local sql = - "DELETE FROM Areas WHERE ID = " .. a_AreaID .. ";" .. - "DELETE FROM AllowedUsers WHERE AreaID = " .. a_AreaID; - if (not(self:DBExec(sql))) then - LOGWARNING(PluginPrefix .. "SQL error while deleting area " .. a_AreaID .. " from world \"" .. a_WorldName .. "\""); - return false; - end - - return true; -end - - - - - ---- Removes the user from the specified area -function cStorage:RemoveUser(a_AreaID, a_UserName, a_WorldName) - assert(a_AreaID); - assert(a_UserName); - assert(a_WorldName); - assert(self); - - -- WorldName is not used yet, because all the worlds share the same DB in this version - - local lcUserName = string.lower(a_UserName); - local sql = "DELETE FROM AllowedUsers WHERE " .. - "AreaID = " .. a_AreaID .. " AND UserName = '" .. lcUserName .. "'"; - if (not(self:DBExec(sql))) then - LOGWARNING("SQL error while removing user " .. a_UserName .. " from area ID " .. a_AreaID); - return false; - end - return true; -end - - - - - ---- Removes the user from all areas in the specified world -function cStorage:RemoveUserAll(a_UserName, a_WorldName) - assert(a_UserName); - assert(a_WorldName); - assert(self); - - local lcUserName = string.lower(a_UserName); - local sql = "DELETE FROM AllowedUsers WHERE UserName = '" .. lcUserName .."'"; - if (not(self:DBExec(sql))) then - LOGWARNING("SQL error while removing user " .. a_UserName .. " from all areas"); - return false; - end - return true; -end - - - - - ---- Calls the callback for each area intersecting the specified coords --- Callback signature: function(ID, MinX, MinZ, MaxX, MaxZ, CreatorName) -function cStorage:ForEachArea(a_BlockX, a_BlockZ, a_WorldName, a_Callback) - assert(a_BlockX); - assert(a_BlockZ); - assert(a_WorldName); - assert(a_Callback); - assert(self); - - -- SQL callback that parses the values and calls our callback - function CallCallback(UserData, NumValues, Values, Names) - if (NumValues ~= 6) then - -- Not enough values returned, skip this row - return 0; - end - local ID = Values[1]; - local MinX = Values[2]; - local MinZ = Values[3]; - local MaxX = Values[4]; - local MaxZ = Values[5]; - local CreatorName = Values[6]; - a_Callback(ID, MinX, MinZ, MaxX, MaxZ, CreatorName); - return 0; - end - - local lcWorldName = string.lower(a_WorldName); - local sql = "SELECT ID, MinX, MinZ, MaxX, MaxZ, CreatorUserName FROM Areas WHERE " .. - "MinX <= " .. a_BlockX .. " AND MaxX >= " .. a_BlockX .. " AND " .. - "MinZ <= " .. a_BlockZ .. " AND MaxZ >= " .. a_BlockZ .. " AND " .. - "WorldName = '" .. lcWorldName .. "'"; - if (not(self:DBExec(sql, CallCallback))) then - LOGWARNING("SQL Error while iterating through areas (cStorage:ForEachArea())"); - return false; - end - return true; -end - - - - - ---- Returns the info on the specified area --- Returns MinX, MinZ, MaxX, MaxZ, CreatorName on success, or nothing on failure -function cStorage:GetArea(a_AreaID, a_WorldName) - assert(a_AreaID); - assert(a_WorldName); - assert(self); - - local MinX, MinZ, MaxX, MaxZ, CreatorName; - local HasValues = false; - - -- SQL callback that parses the values and remembers them in variables - function RememberValues(UserData, NumValues, Values, Names) - if (NumValues ~= 5) then - -- Not enough values returned, skip this row - return 0; - end - MinX = Values[1]; - MinZ = Values[2]; - MaxX = Values[3]; - MaxZ = Values[4]; - CreatorName = Values[5]; - HasValues = true; - return 0; - end - - local lcWorldName = string.lower(a_WorldName); - local sql = "SELECT MinX, MinZ, MaxX, MaxZ, CreatorUserName FROM Areas WHERE " .. - "ID = " .. a_AreaID .. " AND WorldName = '" .. lcWorldName .. "'"; - if (not(self:DBExec(sql, RememberValues))) then - LOGWARNING("SQL Error while getting area info (cStorage:ForEachArea())"); - return; - end - - -- If no data has been retrieved, return nothing - if (not(HasValues)) then - return; - end - - return MinX, MinZ, MaxX, MaxZ, CreatorName; -end - - - - - ---- Calls the callback for each allowed user for the specified area --- Callback signature: function(UserName) -function cStorage:ForEachUserInArea(a_AreaID, a_WorldName, a_Callback) - assert(a_AreaID); - assert(a_WorldName); - assert(a_Callback); - assert(self); - - -- Since in this version all the worlds share a single DB, the a_WorldName parameter is not actually used - -- But this may change in the future, when we have a per-world DB - - local function CallCallback(UserData, NumValues, Values) - if (NumValues ~= 1) then - return 0; - end - a_Callback(Values[1]); - return 0; - end - local sql = "SELECT UserName FROM AllowedUsers WHERE AreaID = " .. a_AreaID; - if (not(self:DBExec(sql, CallCallback))) then - LOGWARNING("SQL error while iterating area users for AreaID" .. a_AreaID); - return false; - end - return true; -end - - - - - ---- Adds the specified usernames to the specified area, if not already present --- a_Users is an array table of usernames to add -function cStorage:AddAreaUsers(a_AreaID, a_WorldName, a_AddedBy, a_Users) - assert(a_AreaID); - assert(a_WorldName); - assert(a_Users); - assert(self); - - -- Convert all usernames to lowercase - for idx, Name in ipairs(a_Users) do - a_Users[idx] = string.lower(Name); - end - - -- Remove from a_Users the usernames already present in the area - local sql = "SELECT UserName FROM AllowedUsers WHERE AreaID = " .. a_AreaID; - local function RemovePresent(UserData, NumValues, Values, Names) - if (NumValues ~= 1) then - -- Invalid response format - return 0; - end - local DBName = Values[1]; - -- Remove the name from a_Users, if exists - for idx, Name in ipairs(a_Users) do - if (Name == DBName) then - table.remove(a_Users, idx); - return 0; - end - end - return 0; - end - if (not(self:DBExec(sql, RemovePresent))) then - LOGWARNING("SQL error while iterating through users"); - return false; - end - - -- Add the users - for idx, Name in ipairs(a_Users) do - local sql = "INSERT INTO AllowedUsers (AreaID, UserName) VALUES (" .. a_AreaID .. ", '" .. Name .. "')"; - if (not(self:DBExec(sql))) then - LOGWARNING("SQL error while adding user " .. Name .. " to area " .. a_AreaID); - end - end - - return true; -end - - - - - -- cgit v1.2.3 From 26b56689a68fd1e068512abd29cfd14c602e6e63 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 10:17:37 +0200 Subject: Updated the nightbuild script for moved plugins --- Nightbuild2008.cmd | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Nightbuild2008.cmd b/Nightbuild2008.cmd index 11e2b3683..0d93380e9 100644 --- a/Nightbuild2008.cmd +++ b/Nightbuild2008.cmd @@ -53,6 +53,15 @@ if errorlevel 1 goto haderror +:: Update the external plugins to the latest revision: +cd MCServer\Plugins\Core +git pull +if errorlevel 1 goto haderror +cd ..\ProtectionAreas +git pull +if errorlevel 1 goto haderror +cd ..\..\.. + :: Get the Git commit ID into an environment var For /f "tokens=1 delims=/. " %%a in ('git log -1 --oneline --no-abbrev-commit') do (set COMMITID=%%a) if errorlevel 1 goto haderror @@ -100,7 +109,7 @@ set FILESUFFIX=%MYYEAR%_%MYMONTH%_%MYDAY%_%MYTIME%_%COMMITID% echo FILESUFFIX=%FILESUFFIX% copy MCServer\MCServer.exe Install\MCServer.exe cd Install -%zip% a -mx9 -y MCServer_Win_%FILESUFFIX%.7z -scsWIN @Zip2008.list +%zip% a -mx9 -y MCServer_Win_%FILESUFFIX%.7z -scsWIN -i@Zip2008.list -xr!*.git* if errorlevel 1 goto haderror cd .. -- cgit v1.2.3 From 78b329a9b5051296649e0cf9f733c543bcb72537 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 09:40:19 +0200 Subject: Removed squirrel plugin remnants --- MCServer/Plugins/SquirrelChatLog.nut | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 MCServer/Plugins/SquirrelChatLog.nut diff --git a/MCServer/Plugins/SquirrelChatLog.nut b/MCServer/Plugins/SquirrelChatLog.nut deleted file mode 100644 index d90cef126..000000000 --- a/MCServer/Plugins/SquirrelChatLog.nut +++ /dev/null @@ -1,13 +0,0 @@ -class SquirrelChatLog extends Plugin -{ - function Initialize() - { - this.AddHook(Hook.Chat); - return true; - } - - function OnChat(Message, Player) - { - ::print(Player.GetName() + ": " + Message); - } -} -- cgit v1.2.3 From 0cb00996de574095fac49e181a11e6a766248743 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 16 Aug 2013 10:48:19 +0200 Subject: Replaced E_ENTITY_TYPE_XXX with cMonster::mtXXX. Also slightly improved the spawning algorithm. --- source/Bindings.cpp | 67 ++++++++------- source/Bindings.h | 2 +- source/BlockEntities/DispenserEntity.cpp | 2 +- source/BlockID.cpp | 67 +++++++-------- source/BlockID.h | 44 ++-------- source/ChunkDef.h | 3 +- source/Items/ItemSpawnEgg.h | 2 +- source/Mobs/AggressiveMonster.cpp | 1 + source/Mobs/Cavespider.cpp | 1 + source/Mobs/Monster.h | 36 +++++++- source/Mobs/PassiveMonster.cpp | 1 + source/Mobs/Skeleton.cpp | 1 + source/Mobs/Zombie.cpp | 1 + source/Mobs/Zombiepigman.cpp | 1 + source/Protocol/Protocol125.cpp | 1 + source/Protocol/Protocol132.cpp | 1 + source/World.cpp | 140 +++++++++++++++++-------------- source/World.h | 5 +- 18 files changed, 207 insertions(+), 169 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 5684b59f7..955032df7 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/15/13 22:11:03. +** Generated automatically by tolua++-1.0.92 on 08/16/13 10:46:12. */ #ifndef __cplusplus @@ -13883,12 +13883,12 @@ static int tolua_AllToLua_cWorld_SpawnMob00(lua_State* tolua_S) double a_PosX = ((double) tolua_tonumber(tolua_S,2,0)); double a_PosY = ((double) tolua_tonumber(tolua_S,3,0)); double a_PosZ = ((double) tolua_tonumber(tolua_S,4,0)); - int a_EntityType = ((int) tolua_tonumber(tolua_S,5,0)); + cMonster::eType a_MonsterType = ((cMonster::eType) (int) tolua_tonumber(tolua_S,5,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnMob'", NULL); #endif { - int tolua_ret = (int) self->SpawnMob(a_PosX,a_PosY,a_PosZ,a_EntityType); + int tolua_ret = (int) self->SpawnMob(a_PosX,a_PosY,a_PosZ,a_MonsterType); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } @@ -28687,6 +28687,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"biHell",biHell); tolua_constant(tolua_S,"biNether",biNether); tolua_constant(tolua_S,"biSky",biSky); + tolua_constant(tolua_S,"biEnd",biEnd); tolua_constant(tolua_S,"biFrozenOcean",biFrozenOcean); tolua_constant(tolua_S,"biFrozenRiver",biFrozenRiver); tolua_constant(tolua_S,"biIcePlains",biIcePlains); @@ -29243,6 +29244,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE); tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE); tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_WITHER",E_META_SPAWN_EGG_WITHER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_BAT",E_META_SPAWN_EGG_BAT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_WITCH",E_META_SPAWN_EGG_WITCH); tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG); tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP); tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW); @@ -29253,35 +29257,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM); tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT); tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_HORSE",E_META_SPAWN_EGG_HORSE); tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER); - tolua_constant(tolua_S,"E_ENTITY_TYPE_CREEPER",E_ENTITY_TYPE_CREEPER); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SKELETON",E_ENTITY_TYPE_SKELETON); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SPIDER",E_ENTITY_TYPE_SPIDER); - tolua_constant(tolua_S,"E_ENTITY_TYPE_GIANT",E_ENTITY_TYPE_GIANT); - tolua_constant(tolua_S,"E_ENTITY_TYPE_ZOMBIE",E_ENTITY_TYPE_ZOMBIE); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SLIME",E_ENTITY_TYPE_SLIME); - tolua_constant(tolua_S,"E_ENTITY_TYPE_GHAST",E_ENTITY_TYPE_GHAST); - tolua_constant(tolua_S,"E_ENTITY_TYPE_ZOMBIE_PIGMAN",E_ENTITY_TYPE_ZOMBIE_PIGMAN); - tolua_constant(tolua_S,"E_ENTITY_TYPE_ENDERMAN",E_ENTITY_TYPE_ENDERMAN); - tolua_constant(tolua_S,"E_ENTITY_TYPE_CAVE_SPIDER",E_ENTITY_TYPE_CAVE_SPIDER); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SILVERFISH",E_ENTITY_TYPE_SILVERFISH); - tolua_constant(tolua_S,"E_ENTITY_TYPE_BLAZE",E_ENTITY_TYPE_BLAZE); - tolua_constant(tolua_S,"E_ENTITY_TYPE_MAGMA_CUBE",E_ENTITY_TYPE_MAGMA_CUBE); - tolua_constant(tolua_S,"E_ENTITY_TYPE_ENDER_DRAGON",E_ENTITY_TYPE_ENDER_DRAGON); - tolua_constant(tolua_S,"E_ENTITY_TYPE_WITHER",E_ENTITY_TYPE_WITHER); - tolua_constant(tolua_S,"E_ENTITY_TYPE_BAT",E_ENTITY_TYPE_BAT); - tolua_constant(tolua_S,"E_ENTITY_TYPE_WITCH",E_ENTITY_TYPE_WITCH); - tolua_constant(tolua_S,"E_ENTITY_TYPE_PIG",E_ENTITY_TYPE_PIG); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SHEEP",E_ENTITY_TYPE_SHEEP); - tolua_constant(tolua_S,"E_ENTITY_TYPE_COW",E_ENTITY_TYPE_COW); - tolua_constant(tolua_S,"E_ENTITY_TYPE_CHICKEN",E_ENTITY_TYPE_CHICKEN); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SQUID",E_ENTITY_TYPE_SQUID); - tolua_constant(tolua_S,"E_ENTITY_TYPE_WOLF",E_ENTITY_TYPE_WOLF); - tolua_constant(tolua_S,"E_ENTITY_TYPE_MOOSHROOM",E_ENTITY_TYPE_MOOSHROOM); - tolua_constant(tolua_S,"E_ENTITY_TYPE_SNOW_GOLEM",E_ENTITY_TYPE_SNOW_GOLEM); - tolua_constant(tolua_S,"E_ENTITY_TYPE_OCELOT",E_ENTITY_TYPE_OCELOT); - tolua_constant(tolua_S,"E_ENTITY_TYPE_IRON_GOLEM",E_ENTITY_TYPE_IRON_GOLEM); - tolua_constant(tolua_S,"E_ENTITY_TYPE_VILLAGER",E_ENTITY_TYPE_VILLAGER); tolua_constant(tolua_S,"dimNether",dimNether); tolua_constant(tolua_S,"dimOverworld",dimOverworld); tolua_constant(tolua_S,"dimEnd",dimEnd); @@ -30553,6 +30530,34 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cMonster","cMonster","cPawn",NULL); tolua_beginmodule(tolua_S,"cMonster"); + tolua_constant(tolua_S,"mtCreeper",cMonster::mtCreeper); + tolua_constant(tolua_S,"mtSkeleton",cMonster::mtSkeleton); + tolua_constant(tolua_S,"mtSpider",cMonster::mtSpider); + tolua_constant(tolua_S,"mtGiant",cMonster::mtGiant); + tolua_constant(tolua_S,"mtZombie",cMonster::mtZombie); + tolua_constant(tolua_S,"mtSlime",cMonster::mtSlime); + tolua_constant(tolua_S,"mtGhast",cMonster::mtGhast); + tolua_constant(tolua_S,"mtZombiePigman",cMonster::mtZombiePigman); + tolua_constant(tolua_S,"mtEnderman",cMonster::mtEnderman); + tolua_constant(tolua_S,"mtCaveSpider",cMonster::mtCaveSpider); + tolua_constant(tolua_S,"mtSilverfish",cMonster::mtSilverfish); + tolua_constant(tolua_S,"mtBlaze",cMonster::mtBlaze); + tolua_constant(tolua_S,"mtMagmaCube",cMonster::mtMagmaCube); + tolua_constant(tolua_S,"mtEnderDragon",cMonster::mtEnderDragon); + tolua_constant(tolua_S,"mtWither",cMonster::mtWither); + tolua_constant(tolua_S,"mtBat",cMonster::mtBat); + tolua_constant(tolua_S,"mtWitch",cMonster::mtWitch); + tolua_constant(tolua_S,"mtPig",cMonster::mtPig); + tolua_constant(tolua_S,"mtSheep",cMonster::mtSheep); + tolua_constant(tolua_S,"mtCow",cMonster::mtCow); + tolua_constant(tolua_S,"mtChicken",cMonster::mtChicken); + tolua_constant(tolua_S,"mtSquid",cMonster::mtSquid); + tolua_constant(tolua_S,"mtWolf",cMonster::mtWolf); + tolua_constant(tolua_S,"mtMooshroom",cMonster::mtMooshroom); + tolua_constant(tolua_S,"mtSnowGolem",cMonster::mtSnowGolem); + tolua_constant(tolua_S,"mtOcelot",cMonster::mtOcelot); + tolua_constant(tolua_S,"mtIronGolem",cMonster::mtIronGolem); + tolua_constant(tolua_S,"mtVillager",cMonster::mtVillager); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cLineBlockTracer","cLineBlockTracer","",NULL); tolua_beginmodule(tolua_S,"cLineBlockTracer"); diff --git a/source/Bindings.h b/source/Bindings.h index eb2146715..a51f3667c 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/15/13 22:11:04. +** Generated automatically by tolua++-1.0.92 on 08/16/13 10:46:13. */ /* Exported function */ diff --git a/source/BlockEntities/DispenserEntity.cpp b/source/BlockEntities/DispenserEntity.cpp index cde67bb41..f2c542c37 100644 --- a/source/BlockEntities/DispenserEntity.cpp +++ b/source/BlockEntities/DispenserEntity.cpp @@ -112,7 +112,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - if (m_World->SpawnMob(MobX, DispY, MobZ, m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0) + if (m_World->SpawnMob(MobX, DispY, MobZ, (cMonster::eType)m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } diff --git a/source/BlockID.cpp b/source/BlockID.cpp index 05506777c..4b4fe5876 100644 --- a/source/BlockID.cpp +++ b/source/BlockID.cpp @@ -7,6 +7,7 @@ #include "BlockID.h" #include "../iniFile/iniFile.h" #include "Item.h" +#include "Mobs/Monster.h" @@ -287,10 +288,10 @@ EMCSBiome StringToBiome(const AString & a_BiomeString) {biTaiga, "Taiga"}, {biSwampland, "Swampland"}, {biRiver, "River"}, - {biHell, "Hell"}, - {biHell, "Nether"}, - {biSky, "Sky"}, - {biSky, "End"}, + {biNether, "Hell"}, + {biNether, "Nether"}, + {biEnd, "Sky"}, + {biEnd, "End"}, {biFrozenOcean, "FrozenOcean"}, {biFrozenRiver, "FrozenRiver"}, {biIcePlains, "IcePlains"}, @@ -328,34 +329,34 @@ int StringToMobType(const AString & a_MobString) const char * m_String; } MobMap [] = { - {E_ENTITY_TYPE_CREEPER, "Creeper"}, - {E_ENTITY_TYPE_SKELETON, "Skeleton"}, - {E_ENTITY_TYPE_SPIDER, "Spider"}, - {E_ENTITY_TYPE_GIANT, "Giant"}, - {E_ENTITY_TYPE_ZOMBIE, "Zombie"}, - {E_ENTITY_TYPE_SLIME, "Slime"}, - {E_ENTITY_TYPE_GHAST, "Ghast"}, - {E_ENTITY_TYPE_ZOMBIE_PIGMAN, "ZombiePigman"}, - {E_ENTITY_TYPE_ENDERMAN, "Enderman"}, - {E_ENTITY_TYPE_CAVE_SPIDER, "CaveSpider"}, - {E_ENTITY_TYPE_SILVERFISH, "SilverFish"}, - {E_ENTITY_TYPE_BLAZE, "Blaze"}, - {E_ENTITY_TYPE_MAGMA_CUBE, "MagmaCube"}, - {E_ENTITY_TYPE_ENDER_DRAGON, "EnderDragon"}, - {E_ENTITY_TYPE_WITHER, "Wither"}, - {E_ENTITY_TYPE_BAT, "Bat"}, - {E_ENTITY_TYPE_WITCH, "Witch"}, - {E_ENTITY_TYPE_PIG, "Pig"}, - {E_ENTITY_TYPE_SHEEP, "Sheep"}, - {E_ENTITY_TYPE_COW, "Cow"}, - {E_ENTITY_TYPE_CHICKEN, "Chicken"}, - {E_ENTITY_TYPE_SQUID, "Squid"}, - {E_ENTITY_TYPE_WOLF, "Wolf"}, - {E_ENTITY_TYPE_MOOSHROOM, "Mushroom"}, - {E_ENTITY_TYPE_SNOW_GOLEM, "SnowGolem"}, - {E_ENTITY_TYPE_OCELOT, "Ocelot"}, - {E_ENTITY_TYPE_IRON_GOLEM, "IronGolem"}, - {E_ENTITY_TYPE_VILLAGER, "Villager"}, + {cMonster::mtCreeper, "Creeper"}, + {cMonster::mtSkeleton, "Skeleton"}, + {cMonster::mtSpider, "Spider"}, + {cMonster::mtGiant, "Giant"}, + {cMonster::mtZombie, "Zombie"}, + {cMonster::mtSlime, "Slime"}, + {cMonster::mtGhast, "Ghast"}, + {cMonster::mtZombiePigman, "ZombiePigman"}, + {cMonster::mtEnderman, "Enderman"}, + {cMonster::mtCaveSpider, "CaveSpider"}, + {cMonster::mtSilverfish, "SilverFish"}, + {cMonster::mtBlaze, "Blaze"}, + {cMonster::mtMagmaCube, "MagmaCube"}, + {cMonster::mtEnderDragon, "EnderDragon"}, + {cMonster::mtWither, "Wither"}, + {cMonster::mtBat, "Bat"}, + {cMonster::mtWitch, "Witch"}, + {cMonster::mtPig, "Pig"}, + {cMonster::mtSheep, "Sheep"}, + {cMonster::mtCow, "Cow"}, + {cMonster::mtChicken, "Chicken"}, + {cMonster::mtSquid, "Squid"}, + {cMonster::mtWolf, "Wolf"}, + {cMonster::mtMooshroom, "Mooshroom"}, + {cMonster::mtSnowGolem, "SnowGolem"}, + {cMonster::mtOcelot, "Ocelot"}, + {cMonster::mtIronGolem, "IronGolem"}, + {cMonster::mtVillager, "Villager"}, }; for (int i = 0; i < ARRAYCOUNT(MobMap); i++) { @@ -364,7 +365,7 @@ int StringToMobType(const AString & a_MobString) return MobMap[i].m_MobType; } } // for i - MobMap[] - return (int)-1; + return -1; } diff --git a/source/BlockID.h b/source/BlockID.h index 58919e1aa..7c7adf26e 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -541,8 +541,8 @@ enum E_META_TRACKS_X = 1, E_META_TRACKS_Z = 0, - // E_ITEM_SPAWN_EGG spawn EntityIDs: - // See also E_ENTITY_TYPE_XXX, since entity type and spawn egg meta are the same + // E_ITEM_SPAWN_EGG metas: + // See also cMonster::eType, since monster type and spawn egg meta are the same E_META_SPAWN_EGG_CREEPER = 50, E_META_SPAWN_EGG_SKELETON = 51, E_META_SPAWN_EGG_SPIDER = 52, @@ -557,6 +557,9 @@ enum E_META_SPAWN_EGG_BLAZE = 61, E_META_SPAWN_EGG_MAGMA_CUBE = 62, E_META_SPAWN_EGG_ENDER_DRAGON = 63, + E_META_SPAWN_EGG_WITHER = 64, + E_META_SPAWN_EGG_BAT = 65, + E_META_SPAWN_EGG_WITCH = 66, E_META_SPAWN_EGG_PIG = 90, E_META_SPAWN_EGG_SHEEP = 91, E_META_SPAWN_EGG_COW = 92, @@ -567,48 +570,15 @@ enum E_META_SPAWN_EGG_SNOW_GOLEM = 97, E_META_SPAWN_EGG_OCELOT = 98, E_META_SPAWN_EGG_IRON_GOLEM = 99, + E_META_SPAWN_EGG_HORSE = 100, E_META_SPAWN_EGG_VILLAGER = 120, } ; -enum -{ - // See also E_META_SPAWN_EGG_XXX, since entity type and spawn egg meta are the same - E_ENTITY_TYPE_CREEPER = 50, - E_ENTITY_TYPE_SKELETON = 51, - E_ENTITY_TYPE_SPIDER = 52, - E_ENTITY_TYPE_GIANT = 53, - E_ENTITY_TYPE_ZOMBIE = 54, - E_ENTITY_TYPE_SLIME = 55, - E_ENTITY_TYPE_GHAST = 56, - E_ENTITY_TYPE_ZOMBIE_PIGMAN = 57, - E_ENTITY_TYPE_ENDERMAN = 58, - E_ENTITY_TYPE_CAVE_SPIDER = 59, - E_ENTITY_TYPE_SILVERFISH = 60, - E_ENTITY_TYPE_BLAZE = 61, - E_ENTITY_TYPE_MAGMA_CUBE = 62, - E_ENTITY_TYPE_ENDER_DRAGON = 63, - E_ENTITY_TYPE_WITHER = 64, - E_ENTITY_TYPE_BAT = 65, - E_ENTITY_TYPE_WITCH = 66, - E_ENTITY_TYPE_PIG = 90, - E_ENTITY_TYPE_SHEEP = 91, - E_ENTITY_TYPE_COW = 92, - E_ENTITY_TYPE_CHICKEN = 93, - E_ENTITY_TYPE_SQUID = 94, - E_ENTITY_TYPE_WOLF = 95, - E_ENTITY_TYPE_MOOSHROOM = 96, - E_ENTITY_TYPE_SNOW_GOLEM = 97, - E_ENTITY_TYPE_OCELOT = 98, - E_ENTITY_TYPE_IRON_GOLEM = 99, - E_ENTITY_TYPE_VILLAGER = 120, -} ; - - - +/// Dimension of a world enum eDimension { dimNether = -1, diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 3e78b59b1..4cc2d15b0 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -76,7 +76,8 @@ enum EMCSBiome biRiver = 7, biHell = 8, // same as Nether biNether = 8, - biSky = 9, + biSky = 9, // same as biEnd + biEnd = 9, biFrozenOcean = 10, biFrozenRiver = 11, biIcePlains = 12, diff --git a/source/Items/ItemSpawnEgg.h b/source/Items/ItemSpawnEgg.h index e563d7e15..5ba0c0ad5 100644 --- a/source/Items/ItemSpawnEgg.h +++ b/source/Items/ItemSpawnEgg.h @@ -33,7 +33,7 @@ public: a_BlockY--; } - if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, a_Item.m_ItemDamage) >= 0) + if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, (cMonster::eType)(a_Item.m_ItemDamage)) >= 0) { if (a_Player->GetGameMode() != 1) { diff --git a/source/Mobs/AggressiveMonster.cpp b/source/Mobs/AggressiveMonster.cpp index c6befa0ed..b266fc502 100644 --- a/source/Mobs/AggressiveMonster.cpp +++ b/source/Mobs/AggressiveMonster.cpp @@ -3,6 +3,7 @@ #include "AggressiveMonster.h" +#include "../World.h" #include "../Vector3f.h" #include "../Player.h" #include "../MersenneTwister.h" diff --git a/source/Mobs/Cavespider.cpp b/source/Mobs/Cavespider.cpp index b547362ad..569aadcc4 100644 --- a/source/Mobs/Cavespider.cpp +++ b/source/Mobs/Cavespider.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Cavespider.h" +#include "../World.h" diff --git a/source/Mobs/Monster.h b/source/Mobs/Monster.h index ea7f935ea..b821285a0 100644 --- a/source/Mobs/Monster.h +++ b/source/Mobs/Monster.h @@ -3,7 +3,6 @@ #include "../Pawn.h" #include "../Defines.h" -#include "../World.h" #include "../BlockID.h" #include "../Item.h" @@ -13,6 +12,7 @@ class Vector3f; class cClientHandle; +class cWorld; @@ -23,7 +23,41 @@ class cMonster : { typedef cPawn super; public: + /// This identifies individual monster type, as well as their network type-ID + enum eType + { + mtCreeper = E_META_SPAWN_EGG_CREEPER, + mtSkeleton = E_META_SPAWN_EGG_SKELETON, + mtSpider = E_META_SPAWN_EGG_SPIDER, + mtGiant = E_META_SPAWN_EGG_GIANT, + mtZombie = E_META_SPAWN_EGG_ZOMBIE, + mtSlime = E_META_SPAWN_EGG_SLIME, + mtGhast = E_META_SPAWN_EGG_GHAST, + mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN, + mtEnderman = E_META_SPAWN_EGG_ENDERMAN, + mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER, + mtSilverfish = E_META_SPAWN_EGG_SILVERFISH, + mtBlaze = E_META_SPAWN_EGG_BLAZE, + mtMagmaCube = E_META_SPAWN_EGG_MAGMA_CUBE, + mtEnderDragon = E_META_SPAWN_EGG_ENDER_DRAGON, + mtWither = E_META_SPAWN_EGG_WITHER, + mtBat = E_META_SPAWN_EGG_BAT, + mtWitch = E_META_SPAWN_EGG_WITCH, + mtPig = E_META_SPAWN_EGG_PIG, + mtSheep = E_META_SPAWN_EGG_SHEEP, + mtCow = E_META_SPAWN_EGG_COW, + mtChicken = E_META_SPAWN_EGG_CHICKEN, + mtSquid = E_META_SPAWN_EGG_SQUID, + mtWolf = E_META_SPAWN_EGG_WOLF, + mtMooshroom = E_META_SPAWN_EGG_MOOSHROOM, + mtSnowGolem = E_META_SPAWN_EGG_SNOW_GOLEM, + mtOcelot = E_META_SPAWN_EGG_OCELOT, + mtIronGolem = E_META_SPAWN_EGG_IRON_GOLEM, + mtVillager = E_META_SPAWN_EGG_VILLAGER, + } ; + // tolua_end + float m_SightDistance; /** Creates the mob object. diff --git a/source/Mobs/PassiveMonster.cpp b/source/Mobs/PassiveMonster.cpp index 96cc1ba8f..7a6140c04 100644 --- a/source/Mobs/PassiveMonster.cpp +++ b/source/Mobs/PassiveMonster.cpp @@ -3,6 +3,7 @@ #include "PassiveMonster.h" #include "../MersenneTwister.h" +#include "../World.h" diff --git a/source/Mobs/Skeleton.cpp b/source/Mobs/Skeleton.cpp index 8dacbece8..bec912afa 100644 --- a/source/Mobs/Skeleton.cpp +++ b/source/Mobs/Skeleton.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Skeleton.h" +#include "../World.h" diff --git a/source/Mobs/Zombie.cpp b/source/Mobs/Zombie.cpp index d0a929519..a6e39d6df 100644 --- a/source/Mobs/Zombie.cpp +++ b/source/Mobs/Zombie.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Zombie.h" +#include "../World.h" diff --git a/source/Mobs/Zombiepigman.cpp b/source/Mobs/Zombiepigman.cpp index 6483e58c5..09b44816f 100644 --- a/source/Mobs/Zombiepigman.cpp +++ b/source/Mobs/Zombiepigman.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Zombiepigman.h" +#include "../World.h" diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 1f2acf50c..e481bb9a7 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -14,6 +14,7 @@ Documentation: #include "Protocol125.h" #include "../ClientHandle.h" +#include "../World.h" #include "ChunkDataSerializer.h" #include "../Entity.h" #include "../Mobs/Monster.h" diff --git a/source/Protocol/Protocol132.cpp b/source/Protocol/Protocol132.cpp index 7a3975537..5bf456ce3 100644 --- a/source/Protocol/Protocol132.cpp +++ b/source/Protocol/Protocol132.cpp @@ -7,6 +7,7 @@ #include "Protocol132.h" #include "../Root.h" #include "../Server.h" +#include "../World.h" #include "../ClientHandle.h" #include "../../CryptoPP/randpool.h" #include "../Item.h" diff --git a/source/World.cpp b/source/World.cpp index 0b74adec1..702e94b56 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -746,55 +746,73 @@ void cWorld::TickSpawnMobs(float a_Dt) int Height = GetHeight((int)SpawnPos.x, (int)SpawnPos.z); int MobType = -1; - if (m_TimeOfDay >= 12000 + 1000) + int Biome = GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z); + switch (Biome) { - if (GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z) == biHell) // Spawn nether mobs + case biNether: { + // Spawn nether mobs switch (nightRand) { - case 5: MobType = E_ENTITY_TYPE_GHAST; break; - case 6: MobType = E_ENTITY_TYPE_ZOMBIE_PIGMAN; break; + case 5: MobType = cMonster::mtGhast; break; + case 6: MobType = cMonster::mtZombiePigman; break; } + break; } - else if (GetBiomeAt((int)SpawnPos.x, (int)SpawnPos.z) == biSky) + + case biEnd: { - switch (nightRand) - { - case 5: MobType = E_ENTITY_TYPE_ENDERMAN; break; - } + // Only endermen spawn in the End + MobType = cMonster::mtEnderman; + break; } - else + + case biMushroomIsland: + case biMushroomShore: { - switch (nightRand) - { - case 0: MobType = E_ENTITY_TYPE_SPIDER; break; - case 1: MobType = E_ENTITY_TYPE_ZOMBIE; break; - case 2: MobType = E_ENTITY_TYPE_ENDERMAN; break; - case 3: MobType = E_ENTITY_TYPE_CREEPER; break; - case 4: MobType = E_ENTITY_TYPE_CAVE_SPIDER; break; - case 7: MobType = E_ENTITY_TYPE_SLIME; break; - case 8: MobType = E_ENTITY_TYPE_SILVERFISH; break; - case 9: MobType = E_ENTITY_TYPE_SKELETON; break; - } + // Mushroom land gets only mooshrooms + MobType = cMonster::mtMooshroom; + break; } - } - else - { - switch (dayRand) + + default: { - case 0: MobType = E_ENTITY_TYPE_CHICKEN; break; - case 1: MobType = E_ENTITY_TYPE_COW; break; - case 2: MobType = E_ENTITY_TYPE_PIG; break; - case 3: MobType = E_ENTITY_TYPE_SHEEP; break; - case 4: MobType = E_ENTITY_TYPE_SQUID; break; - case 5: MobType = E_ENTITY_TYPE_WOLF; break; - } - } + // Overworld biomes depend on whether it's night or day: + if (m_TimeOfDay >= 12000 + 1000) + { + // Night mobs: + switch (nightRand) + { + case 0: MobType = cMonster::mtSpider; break; + case 1: MobType = cMonster::mtZombie; break; + case 2: MobType = cMonster::mtEnderman; break; + case 3: MobType = cMonster::mtCreeper; break; + case 4: MobType = cMonster::mtCaveSpider; break; + case 7: MobType = cMonster::mtSlime; break; + case 8: MobType = cMonster::mtSilverfish; break; + case 9: MobType = cMonster::mtSkeleton; break; + } + } // if (night) + else + { + // During the day: + switch (dayRand) + { + case 0: MobType = cMonster::mtChicken; break; + case 1: MobType = cMonster::mtCow; break; + case 2: MobType = cMonster::mtPig; break; + case 3: MobType = cMonster::mtSheep; break; + case 4: MobType = cMonster::mtSquid; break; + case 5: MobType = cMonster::mtWolf; break; + } + } // else (night) + } // case overworld biomes + } // switch (biome) if (MobType >= 0) { // A proper mob type was selected, now spawn the mob: - SpawnMob(SpawnPos.x, SpawnPos.y, SpawnPos.z, MobType); + SpawnMob(SpawnPos.x, SpawnPos.y, SpawnPos.z, (cMonster::eType)MobType); } } @@ -2553,41 +2571,41 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ) -int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityType) +int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) { cMonster * Monster = NULL; int Size = GetTickRandomNumber(2) + 1; // 1 .. 3 - switch (a_EntityType) - { - case E_ENTITY_TYPE_BAT: Monster = new cBat(); break; - case E_ENTITY_TYPE_BLAZE: Monster = new cBlaze(); break; - case E_ENTITY_TYPE_CAVE_SPIDER: Monster = new cCavespider(); break; - case E_ENTITY_TYPE_CHICKEN: Monster = new cChicken(); break; - case E_ENTITY_TYPE_COW: Monster = new cCow(); break; - case E_ENTITY_TYPE_CREEPER: Monster = new cCreeper(); break; - case E_ENTITY_TYPE_ENDERMAN: Monster = new cEnderman(); break; - case E_ENTITY_TYPE_GHAST: Monster = new cGhast(); break; - case E_ENTITY_TYPE_MAGMA_CUBE: Monster = new cMagmacube(Size); break; - case E_ENTITY_TYPE_MOOSHROOM: Monster = new cMooshroom(); break; - case E_ENTITY_TYPE_OCELOT: Monster = new cOcelot(); break; - case E_ENTITY_TYPE_PIG: Monster = new cPig(); break; - case E_ENTITY_TYPE_SHEEP: Monster = new cSheep(); break; - case E_ENTITY_TYPE_SILVERFISH: Monster = new cSilverfish(); break; - case E_ENTITY_TYPE_SKELETON: Monster = new cSkeleton(); break; - case E_ENTITY_TYPE_SLIME: Monster = new cSlime(Size); break; - case E_ENTITY_TYPE_SPIDER: Monster = new cSpider(); break; - case E_ENTITY_TYPE_SQUID: Monster = new cSquid(); break; - case E_ENTITY_TYPE_VILLAGER: Monster = new cVillager(); break; - case E_ENTITY_TYPE_WITCH: Monster = new cWitch(); break; - case E_ENTITY_TYPE_WOLF: Monster = new cWolf(); break; - case E_ENTITY_TYPE_ZOMBIE: Monster = new cZombie(); break; - case E_ENTITY_TYPE_ZOMBIE_PIGMAN: Monster = new cZombiepigman(); break; + switch (a_MonsterType) + { + case cMonster::mtBat: Monster = new cBat(); break; + case cMonster::mtBlaze: Monster = new cBlaze(); break; + case cMonster::mtCaveSpider: Monster = new cCavespider(); break; + case cMonster::mtChicken: Monster = new cChicken(); break; + case cMonster::mtCow: Monster = new cCow(); break; + case cMonster::mtCreeper: Monster = new cCreeper(); break; + case cMonster::mtEnderman: Monster = new cEnderman(); break; + case cMonster::mtGhast: Monster = new cGhast(); break; + case cMonster::mtMagmaCube: Monster = new cMagmacube(Size); break; + case cMonster::mtMooshroom: Monster = new cMooshroom(); break; + case cMonster::mtOcelot: Monster = new cOcelot(); break; + case cMonster::mtPig: Monster = new cPig(); break; + case cMonster::mtSheep: Monster = new cSheep(); break; + case cMonster::mtSilverfish: Monster = new cSilverfish(); break; + case cMonster::mtSkeleton: Monster = new cSkeleton(); break; + case cMonster::mtSlime: Monster = new cSlime(Size); break; + case cMonster::mtSpider: Monster = new cSpider(); break; + case cMonster::mtSquid: Monster = new cSquid(); break; + case cMonster::mtVillager: Monster = new cVillager(); break; + case cMonster::mtWitch: Monster = new cWitch(); break; + case cMonster::mtWolf: Monster = new cWolf(); break; + case cMonster::mtZombie: Monster = new cZombie(); break; + case cMonster::mtZombiePigman: Monster = new cZombiepigman(); break; default: { - LOGWARNING("%s: Unhandled entity type: %d. Not spawning.", __FUNCTION__, a_EntityType); + LOGWARNING("%s: Unhandled monster type: %d. Not spawning.", __FUNCTION__, a_MonsterType); return -1; } } diff --git a/source/World.h b/source/World.h index 8525eebe5..5d3de06d0 100644 --- a/source/World.h +++ b/source/World.h @@ -20,6 +20,7 @@ #include "Defines.h" #include "LightingThread.h" #include "Item.h" +#include "Mobs/Monster.h" @@ -546,8 +547,8 @@ public: bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - /// Spawns a mob of the specified entity type. Returns the mob's EntityID if recognized and spawned, <0 otherwise - int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityType); // tolua_export + /// Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise + int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType); // tolua_export /// Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); } -- cgit v1.2.3