From 9f03682258d949b3b6ddd4fedec93977dedbadde Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 29 May 2014 13:34:38 +0200 Subject: Enderman attacks a player if he's looking at him. --- src/Mobs/Enderman.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Mobs/Enderman.h | 1 + 2 files changed, 91 insertions(+) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index becc99a86..bd5ed85f1 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -2,6 +2,66 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Enderman.h" +#include "../Entities/Player.h" + + + + +/////////////////////////////////////////////////////////////////////////// +// cPlayerLookCheck +class cPlayerLookCheck : + public cPlayerListCallback +{ +public: + cPlayerLookCheck(Vector3d a_EndermanPos) : + m_EndermanPos(a_EndermanPos), + m_Player(NULL) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + // Don't check players who are in creative gamemode. + if (a_Player->IsGameModeCreative()) + { + return false; + } + + Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); + + // Don't check players who are more then 64 blocks away. + if (Direction.SqrLength() > 64) + { + return false; + } + + // Don't check if the player has a pumpkin on his head. + if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) + { + return false; + } + + Direction.Normalize(); + + Vector3d LookVector = a_Player->GetLookVector(); + LookVector.Normalize(); + + if ((Direction - LookVector).SqrLength() > 0.02) + { + return false; + } + + // TODO: Don't attack the player if there is a wall between the player and the enderman. + m_Player = a_Player; + return true; + } + + cPlayer * GetPlayer(void) const {return m_Player;} + bool HasFoundPlayer(void) const {return (m_Player != NULL);} +protected: + cPlayer * m_Player; + Vector3d m_EndermanPos; +} ; @@ -32,3 +92,33 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) +void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_Target != NULL) + { + return; + } + + cPlayerLookCheck Callback(GetPosition()); + if (!m_World->ForEachPlayer(Callback)) + { + return; + } + + if (!Callback.HasFoundPlayer()) + { + return; + } + + m_bIsScreaming = true; + m_Target = Callback.GetPlayer(); + + m_World->BroadcastEntityMetadata(*this); +} + + + + + diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index 32e40e70b..be6e7bdf4 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -18,6 +18,7 @@ public: CLASS_PROTODEF(cEnderman); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3 From 806130a967685b0708b51afc576df09d70d47d79 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 29 May 2014 14:00:12 +0200 Subject: Swapped m_Player and m_EndermanPos --- src/Mobs/Enderman.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index bd5ed85f1..40782d0b0 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -14,8 +14,8 @@ class cPlayerLookCheck : { public: cPlayerLookCheck(Vector3d a_EndermanPos) : - m_EndermanPos(a_EndermanPos), - m_Player(NULL) + m_Player(NULL), + m_EndermanPos(a_EndermanPos) { } -- cgit v1.2.3 From 5d4f70a7a52e986343bddde2104f07c797c574c9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 09:19:55 +0100 Subject: Improved Enderman code --- src/Mobs/Enderman.cpp | 45 ++++++++++++++++++++++++++++++++------------- src/Mobs/Enderman.h | 3 ++- 2 files changed, 34 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 40782d0b0..416b541ed 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -3,6 +3,7 @@ #include "Enderman.h" #include "../Entities/Player.h" +#include "../Tracer.h" @@ -51,13 +52,19 @@ public: return false; } - // TODO: Don't attack the player if there is a wall between the player and the enderman. + cTracer LineOfSight(a_Player->GetWorld()); + if (LineOfSight.Trace(m_EndermanPos, Direction, (int)Direction.Length())) + { + // No direct line of sight + return false; + } + m_Player = a_Player; return true; } - cPlayer * GetPlayer(void) const {return m_Player;} - bool HasFoundPlayer(void) const {return (m_Player != NULL);} + cPlayer * GetPlayer(void) const { return m_Player; } + protected: cPlayer * m_Player; Vector3d m_EndermanPos; @@ -92,33 +99,45 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) -void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) -{ - super::Tick(a_Dt, a_Chunk); - +void cEnderman::CheckEventSeePlayer() +{ if (m_Target != NULL) { return; } cPlayerLookCheck Callback(GetPosition()); - if (!m_World->ForEachPlayer(Callback)) + if (m_World->ForEachPlayer(Callback)) { return; } + + ASSERT(Callback.GetPlayer() != NULL); - if (!Callback.HasFoundPlayer()) + int CX, CZ; + cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, CX, CZ); + if (!GetWorld()->IsChunkLighted(CX, CZ)) { + GetWorld()->QueueLightChunk(CX, CZ); return; } - m_bIsScreaming = true; - m_Target = Callback.GetPlayer(); - - m_World->BroadcastEntityMetadata(*this); + if ((GetWorld()->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() < 15) && !Callback.GetPlayer()->IsGameModeCreative()) + { + super::EventSeePlayer(Callback.GetPlayer()); + m_EMState = CHASING; + m_bIsScreaming = true; + GetWorld()->BroadcastEntityMetadata(*this); + } } +void cEnderman::EventLosePlayer() +{ + super::EventLosePlayer(); + m_bIsScreaming = false; + GetWorld()->BroadcastEntityMetadata(*this); +} \ No newline at end of file diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index be6e7bdf4..044b40511 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -18,7 +18,8 @@ public: CLASS_PROTODEF(cEnderman); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void CheckEventSeePlayer(void) override; + virtual void EventLosePlayer(void) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3 From 0690788cdfefbec3c74057e0b60d9f5aae935303 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 4 Jun 2014 14:16:24 +0100 Subject: Replaced strange algebra with dot product. 10 degrees is a completely arbitary constant I pulled from nowhere. Feel free to adjust this value. --- src/Mobs/Enderman.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 416b541ed..d26639a75 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -42,12 +42,14 @@ public: return false; } - Direction.Normalize(); Vector3d LookVector = a_Player->GetLookVector(); - LookVector.Normalize(); + double dot = Direction.Dot(LookVector); - if ((Direction - LookVector).SqrLength() > 0.02) + // 0.09 rad ~ 5 degrees. + // If the players crosshars are 10 degrees from the line linking the endermen + // It counts as looking. + if (dot > cos(0.09)) { return false; } @@ -140,4 +142,4 @@ void cEnderman::EventLosePlayer() super::EventLosePlayer(); m_bIsScreaming = false; GetWorld()->BroadcastEntityMetadata(*this); -} \ No newline at end of file +} -- cgit v1.2.3 From afda11a495de5b48ad17334da0e3f3b801d02f9b Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 30 Jun 2014 19:33:10 +0100 Subject: Changed comment --- src/Mobs/Enderman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index d26639a75..6b7a22757 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -47,7 +47,7 @@ public: double dot = Direction.Dot(LookVector); // 0.09 rad ~ 5 degrees. - // If the players crosshars are 10 degrees from the line linking the endermen + // If the players crosshair is within 5 degrees of the endermen // It counts as looking. if (dot > cos(0.09)) { -- cgit v1.2.3 From f79e68266426993af94f811afc8296e7b159462a Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 00:03:00 +0200 Subject: Fixed plugin count and fixed plugin loading, when settings.ini was regenerated. --- src/Bindings/PluginManager.cpp | 46 +++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 088b92a6d..1d97d1331 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -124,44 +124,58 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni) // Check if the Plugins section exists. int KeyNum = a_SettingsIni.FindKey("Plugins"); - // If it does, how many plugins are there? - int NumPlugins = ((KeyNum != -1) ? (a_SettingsIni.GetNumValues(KeyNum)) : 0); - if (KeyNum == -1) { InsertDefaultPlugins(a_SettingsIni); + KeyNum = a_SettingsIni.FindKey("Plugins"); } - else if (NumPlugins > 0) + + // How many plugins are there? + int NumPlugins = a_SettingsIni.GetNumValues(KeyNum); + + for (int i = 0; i < NumPlugins; i++) { - for (int i = 0; i < NumPlugins; i++) + AString ValueName = a_SettingsIni.GetValueName(KeyNum, i); + if (ValueName.compare("Plugin") == 0) { - AString ValueName = a_SettingsIni.GetValueName(KeyNum, i); - if (ValueName.compare("Plugin") == 0) + AString PluginFile = a_SettingsIni.GetValue(KeyNum, i); + if (!PluginFile.empty()) { - AString PluginFile = a_SettingsIni.GetValue(KeyNum, i); - if (!PluginFile.empty()) + if (m_Plugins.find(PluginFile) != m_Plugins.end()) { - if (m_Plugins.find(PluginFile) != m_Plugins.end()) - { - LoadPlugin(PluginFile); - } + LoadPlugin(PluginFile); } } } } + + // Remove invalid plugins from the PluginMap. + for (PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end();) + { + if (itr->second == NULL) + { + PluginMap::iterator thiz = itr; + ++thiz; + m_Plugins.erase(itr); + itr = thiz; + continue; + } + ++itr; + } + size_t NumLoadedPlugins = GetNumPlugins(); if (NumLoadedPlugins == 0) { LOG("-- No Plugins Loaded --"); } - else if (NumLoadedPlugins > 1) + else if (NumLoadedPlugins == 1) { - LOG("-- Loaded %i Plugins --", (int)NumLoadedPlugins); + LOG("-- Loaded 1 Plugin --"); } else { - LOG("-- Loaded 1 Plugin --"); + LOG("-- Loaded %i Plugins --", (int)NumLoadedPlugins); } CallHookPluginsLoaded(); } -- cgit v1.2.3 From a5cca16abe524fdbd756908ac157a0c9881463f3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 00:39:39 +0200 Subject: Add "Broadcasting" settings to world.ini --- src/Entities/Player.cpp | 14 ++++++++------ src/Root.cpp | 4 ++-- src/Server.h | 4 ++-- src/World.cpp | 3 +++ src/World.h | 8 +++++++- 5 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index fcc8eb9a0..393afc3b6 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -890,7 +890,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! - if (a_TDI.Attacker == NULL) + if ((a_TDI.Attacker == NULL) && m_World->ShouldBroadcastDeathMessages()) { AString DamageText; switch (a_TDI.DamageType) @@ -1208,11 +1208,13 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach) } else { - // First time, announce it - cCompositeChat Msg; - Msg.SetMessageType(mtSuccess); - Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach)); - m_World->BroadcastChat(Msg); + if (m_World->ShouldBroadcastAchievementMessages()) + { + cCompositeChat Msg; + Msg.SetMessageType(mtSuccess); + Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach)); + m_World->BroadcastChat(Msg); + } // Increment the statistic StatValue New = m_Stats.AddValue(a_Ach); diff --git a/src/Root.cpp b/src/Root.cpp index b03a13382..efa21b775 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -269,12 +269,12 @@ void cRoot::LoadWorlds(cIniFile & IniFile) { // First get the default world AString DefaultWorldName = IniFile.GetValueSet("Worlds", "DefaultWorld", "world"); - m_pDefaultWorld = new cWorld( DefaultWorldName.c_str()); + m_pDefaultWorld = new cWorld(DefaultWorldName.c_str()); m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; // Then load the other worlds unsigned int KeyNum = IniFile.FindKey("Worlds"); - unsigned int NumWorlds = IniFile.GetNumValues( KeyNum); + unsigned int NumWorlds = IniFile.GetNumValues(KeyNum); if (NumWorlds <= 0) { return; diff --git a/src/Server.h b/src/Server.h index b03359f03..c1640b388 100644 --- a/src/Server.h +++ b/src/Server.h @@ -63,12 +63,12 @@ public: // tolua_export const AString & GetDescription(void) const {return m_Description; } // Player counts: - int GetMaxPlayers(void) const {return m_MaxPlayers; } + int GetMaxPlayers(void) const { return m_MaxPlayers; } int GetNumPlayers(void) const; void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } // Hardcore mode or not: - bool IsHardcore(void) const {return m_bIsHardcore; } + bool IsHardcore(void) const { return m_bIsHardcore; } // tolua_end diff --git a/src/World.cpp b/src/World.cpp index 7ad350e24..ff393bc2b 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -522,6 +522,9 @@ void cWorld::Start(void) AString Dimension = IniFile.GetValueSet("General", "Dimension", "Overworld"); m_Dimension = StringToDimension(Dimension); + m_BroadcastDeathMessages = IniFile.GetValueSetB("Broadcasting", "BroadcastDeathMessages", true); + m_BroadcastAchievementMessages = IniFile.GetValueSetB("Broadcasting", "BroadcastAchievementMessages", true); + // Try to find the "SpawnPosition" key and coord values in the world configuration, set the flag if found int KeyNum = IniFile.FindKey("SpawnPosition"); m_IsSpawnExplicitlySet = diff --git a/src/World.h b/src/World.h index 9658178ae..cb77361f6 100644 --- a/src/World.h +++ b/src/World.h @@ -622,7 +622,10 @@ public: bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } - + + bool ShouldBroadcastDeathMessages(void) const { return m_BroadcastDeathMessages; } + bool ShouldBroadcastAchievementMessages(void) const { return m_BroadcastAchievementMessages; } + // tolua_end /** Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead */ @@ -842,6 +845,9 @@ private: double m_SpawnY; double m_SpawnZ; + bool m_BroadcastDeathMessages; + bool m_BroadcastAchievementMessages; + double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs -- cgit v1.2.3 From 7f9f46c9114837a6edaae53385b7b7970b91abbd Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 13:47:21 +0200 Subject: Fixed group color's. --- src/ClientHandle.cpp | 19 ++++--------------- src/GroupManager.cpp | 2 +- 2 files changed, 5 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e4ad218a2..116ea459e 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1973,28 +1973,17 @@ void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlock void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData) { - bool ShouldAppendChatPrefixes = true; - - if (GetPlayer()->GetWorld() == NULL) + cWorld * World = GetPlayer()->GetWorld(); + if (World == NULL) { - cWorld * World = cRoot::Get()->GetWorld(GetPlayer()->GetLoadedWorldName()); + World = cRoot::Get()->GetWorld(GetPlayer()->GetLoadedWorldName()); if (World == NULL) { World = cRoot::Get()->GetDefaultWorld(); } - - if (!World->ShouldUseChatPrefixes()) - { - ShouldAppendChatPrefixes = false; - } - } - else if (!GetPlayer()->GetWorld()->ShouldUseChatPrefixes()) - { - ShouldAppendChatPrefixes = false; } - AString Message = FormatMessageType(ShouldAppendChatPrefixes, a_ChatPrefix, a_AdditionalData); - + AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData); m_Protocol->SendChat(Message.append(a_Message)); } diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index 32c2f1c97..bc9bb67be 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -153,7 +153,7 @@ bool cGroupManager::LoadGroups() AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { - Group->SetColor(cChatColor::Delimiter + Color[0]); + Group->SetColor(cChatColor::Delimiter + Color); } else { -- cgit v1.2.3 From 9be92fa71df5620421c5f64cfa21cb6448a7686c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 20:44:00 +0200 Subject: Use Color[0]. --- src/GroupManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index bc9bb67be..e03f8bca3 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -153,7 +153,7 @@ bool cGroupManager::LoadGroups() AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { - Group->SetColor(cChatColor::Delimiter + Color); + Group->SetColor(cChatColor::Delimiter + AString(&Color[0])); } else { -- cgit v1.2.3 From 3d730403278bca630856ce7d275aed920aa20235 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 21:14:45 +0200 Subject: Use AString(1, Color[0]) --- src/GroupManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index e03f8bca3..f1f86dc0f 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -153,7 +153,7 @@ bool cGroupManager::LoadGroups() AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { - Group->SetColor(cChatColor::Delimiter + AString(&Color[0])); + Group->SetColor(cChatColor::Delimiter + AString(1, Color[0])); } else { -- cgit v1.2.3 From 2bdc2701f4208f5a705fafceec3685a9834714a1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 27 Jul 2014 21:58:00 +0200 Subject: Change Group->SetColor() again. --- src/GroupManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index f1f86dc0f..4c3dfc6f0 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -153,7 +153,7 @@ bool cGroupManager::LoadGroups() AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { - Group->SetColor(cChatColor::Delimiter + AString(1, Color[0])); + Group->SetColor(AString(cChatColor::Delimiter) + Color[0]); } else { -- cgit v1.2.3 From f5f9656917c0cb0cc68aee50178aafd3f24c417f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 28 Jul 2014 12:37:48 +0200 Subject: cAuthenticator: Added GetUUIDsFromPlayerNames(). --- src/Protocol/Authenticator.cpp | 99 ++++++++++++++++++++++++++++++++++++++++-- src/Protocol/Authenticator.h | 20 +++++++++ 2 files changed, 116 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 2a7cbc7bc..75721589f 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -17,6 +17,8 @@ #define DEFAULT_AUTH_SERVER "sessionserver.mojang.com" #define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%" +#define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" +#define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" /** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert: Downloaded from http://certs.starfieldtech.com/repository/ */ @@ -83,6 +85,8 @@ cAuthenticator::cAuthenticator(void) : super("cAuthenticator"), m_Server(DEFAULT_AUTH_SERVER), m_Address(DEFAULT_AUTH_ADDRESS), + m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), + m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_ShouldAuthenticate(true) { } @@ -102,9 +106,11 @@ cAuthenticator::~cAuthenticator() void cAuthenticator::ReadINI(cIniFile & IniFile) { - m_Server = IniFile.GetValueSet("Authentication", "Server", DEFAULT_AUTH_SERVER); - m_Address = IniFile.GetValueSet("Authentication", "Address", DEFAULT_AUTH_ADDRESS); + m_Server = IniFile.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER); + m_Address = IniFile.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS); m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); + m_NameToUUIDServer = IniFile.GetValueSet ("Authentication", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); + m_NameToUUIDAddress = IniFile.GetValueSet ("Authentication", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); } @@ -151,6 +157,93 @@ void cAuthenticator::Stop(void) +AStringVector cAuthenticator::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames) +{ + AStringVector res; + + // Create the request body - a JSON containing all the playernames: + Json::Value root; + for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) + { + Json::Value req(*itr); + root.append(req); + } // for itr - a_PlayerNames[] + Json::FastWriter Writer; + AString RequestBody = Writer.write(root); + + // Create the HTTP request: + AString Request; + Request += "POST " + m_NameToUUIDAddress + " HTTP/1.1\r\n"; + Request += "Host: " + m_NameToUUIDServer + "\r\n"; + Request += "User-Agent: MCServer\r\n"; + Request += "Connection: close\r\n"; + Request += "Content-Type: application/json\r\n"; + Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); + Request += "\r\n"; + Request += RequestBody; + + // Get the response from the server: + AString Response; + if (!SecureGetFromAddress(StarfieldCACert(), m_NameToUUIDServer, Request, Response)) + { + return res; + } + + // Check the HTTP status line: + const AString Prefix("HTTP/1.1 200 OK"); + AString HexDump; + if (Response.compare(0, Prefix.size(), Prefix)) + { + LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return res; + } + + // Erase the HTTP headers from the response: + size_t idxHeadersEnd = Response.find("\r\n\r\n"); + if (idxHeadersEnd == AString::npos) + { + LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return res; + } + Response.erase(0, idxHeadersEnd + 4); + + // Parse the returned string into Json: + Json::Reader reader; + if (!reader.parse(Response, root, false) || !root.isArray()) + { + LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); + LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return res; + } + + // Fill in the resulting array; do not expect to get the UUIDs in the same order as the inputs: + size_t len = a_PlayerNames.size(); + size_t JsonCount = root.size(); + res.resize(len); + for (size_t idx = 0; idx < len; idx++) // For each input username... + { + const AString & InputName = a_PlayerNames[idx]; + for (size_t IdxJson = 0; IdxJson < JsonCount; ++IdxJson) + { + Json::Value & Val = root[IdxJson]; + AString JsonName = Val.get("name", "").asString(); + if (NoCaseCompare(JsonName, InputName) == 0) + { + res[idx] = Val.get("id", "").asString(); + break; + } + } // for IdxJson - root[] + } // for idx - a_PlayerNames[] / res[] + + return res; +} + + + + + void cAuthenticator::Execute(void) { for (;;) @@ -307,7 +400,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S a_UUID = root.get("id", "").asString(); a_Properties = root["properties"]; - // If the UUID doesn't contain the hashes, insert them at the proper places: + // If the UUID doesn't contain the dashes, insert them at the proper places: if (a_UUID.size() == 32) { a_UUID.insert(8, "-"); diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 244d94c0b..82ecb1f7a 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -52,6 +52,12 @@ public: /** Stops the authenticator thread. The thread may be started and stopped repeatedly */ void Stop(void); + + /** Converts the player names into UUIDs. + a_PlayerName[idx] will be converted to UUID and returned as idx-th value + The UUID will be empty on error. + Blocking operation, do not use in world-tick thread! */ + AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName); private: @@ -76,8 +82,22 @@ private: cUserList m_Queue; cEvent m_QueueNonempty; + /** The server that is to be contacted for auth / UUID conversions */ AString m_Server; + + /** The URL to use for auth, without server part. + %USERNAME% will be replaced with actual user name. + %SERVERID% will be replaced with server's ID. + For example "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%". */ AString m_Address; + + /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */ + AString m_NameToUUIDServer; + + /** The URL to use for converting player names to UUIDs, without server part. + For example "/profiles/page/1". */ + AString m_NameToUUIDAddress; + AString m_PropertiesAddress; bool m_ShouldAuthenticate; -- cgit v1.2.3 From 1acd03f96f9b1133e1f76d76004f5fcddd0c4788 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 28 Jul 2014 17:09:39 +0200 Subject: Added cClientHandle:GetUUIDsFromPlayerNames() to Lua API. --- src/Bindings/ManualBindings.cpp | 65 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index df9687fc0..28ee00b36 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -26,6 +26,7 @@ #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "../LineBlockTracer.h" +#include "../Protocol/Authenticator.h" #include "../WorldStorage/SchematicFileSerializer.h" #include "../CompositeChat.h" @@ -2156,6 +2157,63 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L) +static int tolua_cClientHandle_GetUUIDsFromPlayerNames(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cClientHandle") || + !S.CheckParamTable(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Convert the input table into AStringVector: + AStringVector PlayerNames; + int NumNames = luaL_getn(L, 2); + PlayerNames.reserve(NumNames); + for (int i = 1; i <= NumNames; i++) + { + lua_rawgeti(L, 2, i); + AString Name; + S.GetStackValue(3, Name); + if (!Name.empty()) + { + PlayerNames.push_back(Name); + } + lua_pop(L, 1); + } + + // Push the output table onto the stack: + lua_newtable(L); // stack index 3 + + // Get the UUIDs: + AStringVector UUIDs = cRoot::Get()->GetAuthenticator().GetUUIDsFromPlayerNames(PlayerNames); + if (UUIDs.size() != PlayerNames.size()) + { + // A hard error has occured while processing the request, no UUIDs were returned. Return an empty table: + return 1; + } + + // Convert to output table, PlayerName -> UUID: + for (int i = 0; i < NumNames; i++) + { + if (UUIDs[i].empty()) + { + // No UUID was provided for PlayerName[i], skip it in the resulting table + continue; + } + lua_pushlstring(L, UUIDs[i].c_str(), UUIDs[i].length()); + lua_setfield(L, 3, PlayerNames[i].c_str()); + } + return 1; +} + + + + + static int Lua_ItemGrid_GetSlotCoords(lua_State * L) { tolua_Error tolua_err; @@ -3083,9 +3141,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cClientHandle"); - tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); - tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); - tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage); + tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); + tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); + tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage); + tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cClientHandle_GetUUIDsFromPlayerNames); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cItemGrid"); -- cgit v1.2.3 From adae2b70b1733a280fe342ca6d0dca7e37301f4f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 29 Jul 2014 22:31:31 +0200 Subject: Added cBlockInfo::CanBeTerraformed and made finishers use it I might have forgotten some of them though --- src/BlockInfo.cpp | 21 +++++++++++++++++++++ src/BlockInfo.h | 4 ++++ src/Generating/Caves.cpp | 24 ++---------------------- src/Generating/RoughRavines.cpp | 26 ++++---------------------- 4 files changed, 31 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 602deb26d..311a53c42 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -17,6 +17,7 @@ cBlockInfo::cBlockInfo() , m_IsSnowable(false) , m_IsSolid(true) , m_FullyOccupiesVoxel(false) + , m_CanBeTerraformed(false) , m_Handler(NULL) {} @@ -548,6 +549,26 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; + + + // Blocks that can be terraformed + a_Info[E_BLOCK_COAL_ORE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_COBBLESTONE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_DIAMOND_ORE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_DIRT ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_GOLD_ORE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_GRASS ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_GRAVEL ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_HARDENED_CLAY ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_IRON_ORE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_MYCELIUM ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_NETHERRACK ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_REDSTONE_ORE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_CanBeTerraformed = true; + a_Info[E_BLOCK_SAND ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_SANDSTONE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_STAINED_CLAY ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_STONE ].m_CanBeTerraformed = true; } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index e6ce566c5..4c66c095a 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -45,6 +45,9 @@ public: /** Does this block fully occupy its voxel - is it a 'full' block? */ bool m_FullyOccupiesVoxel; + /** Can a finisher change it? */ + bool m_CanBeTerraformed; + // tolua_end /** Associated block handler. */ @@ -60,6 +63,7 @@ public: inline static bool IsSnowable (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSnowable; } inline static bool IsSolid (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSolid; } inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; } + inline static bool CanBeTerraformed (BLOCKTYPE a_Type) { return Get(a_Type).m_CanBeTerraformed; } // tolua_end diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 3b71efb57..6fc371958 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -497,29 +497,9 @@ void cCaveTunnel::ProcessChunk( int SqDist = (DifX - x) * (DifX - x) + (DifY - y) * (DifY - y) + (DifZ - z) * (DifZ - z); if (4 * SqDist <= SqRad) { - switch (cChunkDef::GetBlock(a_BlockTypes, x, y, z)) + if (cBlockInfo::CanBeTerraformed(cChunkDef::GetBlock(a_BlockTypes, x, y, z))) { - // Only carve out these specific block types - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_STONE: - case E_BLOCK_COBBLESTONE: - case E_BLOCK_GRAVEL: - case E_BLOCK_SAND: - case E_BLOCK_SANDSTONE: - case E_BLOCK_SOULSAND: - case E_BLOCK_NETHERRACK: - case E_BLOCK_COAL_ORE: - case E_BLOCK_IRON_ORE: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_DIAMOND_ORE: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR); - break; - } - default: break; + cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR); } } } // for y diff --git a/src/Generating/RoughRavines.cpp b/src/Generating/RoughRavines.cpp index badc7768e..2ee3704b3 100644 --- a/src/Generating/RoughRavines.cpp +++ b/src/Generating/RoughRavines.cpp @@ -201,29 +201,11 @@ protected: { continue; } - switch (a_ChunkDesc.GetBlockType(x, y, z)) + + if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z))) { - // Only carve out these specific block types - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_STONE: - case E_BLOCK_COBBLESTONE: - case E_BLOCK_GRAVEL: - case E_BLOCK_SAND: - case E_BLOCK_SANDSTONE: - case E_BLOCK_NETHERRACK: - case E_BLOCK_COAL_ORE: - case E_BLOCK_IRON_ORE: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_DIAMOND_ORE: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR); - break; - } - default: break; - } // switch (BlockType) + a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR); + } } // for y } // for x, z - a_BlockTypes } // for itr - m_Points[] -- cgit v1.2.3 From 931443ac67cefade2ebd0d29fd65a49d22293ea2 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 29 Jul 2014 22:40:40 +0200 Subject: Added soulsand to the terraformed list. --- src/BlockInfo.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 311a53c42..4bc3fbbdc 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -567,6 +567,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_CanBeTerraformed = true; a_Info[E_BLOCK_SAND ].m_CanBeTerraformed = true; a_Info[E_BLOCK_SANDSTONE ].m_CanBeTerraformed = true; + a_Info[E_BLOCK_SOULSAND ].m_CanBeTerraformed = true; a_Info[E_BLOCK_STAINED_CLAY ].m_CanBeTerraformed = true; a_Info[E_BLOCK_STONE ].m_CanBeTerraformed = true; } -- cgit v1.2.3 From 9a4d80fc3b9dbaa09c8e6d9e8021762a486f280f Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 00:45:03 +0200 Subject: Fixed compile error with clang. --- src/Generating/FinishGen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index ed32768b3..cf84a0336 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -163,7 +163,7 @@ public: m_Amount(a_Amount) { // Initialize all the block types. - for (int idx = 0; idx < ARRAYCOUNT(m_IsAllowedBelow); ++idx) + for (size_t idx = 0; idx < (size_t)ARRAYCOUNT(m_IsAllowedBelow); ++idx) { m_IsAllowedBelow[idx] = false; } @@ -175,7 +175,7 @@ public: } // Initialize all the biome types. - for (int idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx) + for (size_t idx = 0; idx < (size_t)ARRAYCOUNT(m_IsBiomeAllowed); ++idx) { m_IsBiomeAllowed[idx] = false; } -- cgit v1.2.3 From 438e4088d6a38f9904a36f2e1a358965d9fb4a26 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 01:22:51 +0200 Subject: Changed size_t to 'unsigned long' --- src/Generating/FinishGen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index cf84a0336..7171036e2 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -163,7 +163,7 @@ public: m_Amount(a_Amount) { // Initialize all the block types. - for (size_t idx = 0; idx < (size_t)ARRAYCOUNT(m_IsAllowedBelow); ++idx) + for (unsigned long idx = 0; idx < ARRAYCOUNT(m_IsAllowedBelow); ++idx) { m_IsAllowedBelow[idx] = false; } @@ -175,7 +175,7 @@ public: } // Initialize all the biome types. - for (size_t idx = 0; idx < (size_t)ARRAYCOUNT(m_IsBiomeAllowed); ++idx) + for (unsigned long idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx) { m_IsBiomeAllowed[idx] = false; } -- cgit v1.2.3 From 487c57242964ef4a86fc4f41c1c538d9df9ec892 Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 29 Jul 2014 19:14:56 -0700 Subject: Entity.h: Moved constants out of some unnamed enum --- src/Entities/Entity.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index e66194ca2..b9c280b6b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -128,20 +128,20 @@ public: esFireworkExploding = 17, } ; - enum - { - FIRE_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in fire - FIRE_DAMAGE = 1, ///< How much damage to deal when standing in fire - LAVA_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in lava - LAVA_DAMAGE = 5, ///< How much damage to deal when standing in lava - BURN_TICKS_PER_DAMAGE = 20, ///< How many ticks to wait between damaging an entity when it is burning - BURN_DAMAGE = 1, ///< How much damage to deal when the entity is burning - BURN_TICKS = 200, ///< How long to keep an entity burning after it has stood in lava / fire - MAX_AIR_LEVEL = 300, ///< Maximum air an entity can have - DROWNING_TICKS = 20, ///< Number of ticks per heart of damage - VOID_BOUNDARY = -46, ///< At what position Y to begin applying void damage - FALL_DAMAGE_HEIGHT = 4 ///< At what position Y fall damage is applied - } ; + static const int FIRE_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in fire + static const int FIRE_DAMAGE = 1; ///< Damage to deal when standing in fire + static const int LAVA_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in lava + static const int LAVA_DAMAGE = 5; ///< Damage to deal when standing in lava + static const int BURN_TICKS_PER_DAMAGE = 20; ///< Ticks to wait between damaging an entity when it is burning + static const int BURN_DAMAGE = 1; ///< Damage to deal when the entity is burning + + static const int BURN_TICKS = 200; ///< Ticks to keep an entity burning after it has stood in lava / fire + + static const int MAX_AIR_LEVEL = 300; ///< Maximum air an entity can have + static const int DROWNING_TICKS = 20; ///< Number of ticks per heart of damage + + static const int VOID_BOUNDARY = -46; ///< Y position to begin applying void damage + static const int FALL_DAMAGE_HEIGHT = 4; ///< Y difference after which fall damage is applied cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); virtual ~cEntity(); -- cgit v1.2.3 From 7022ae79886a9f90f30ff54387702d406b723837 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 07:08:29 +0200 Subject: Fixed FinishGen.h types. --- src/Generating/FinishGen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 7171036e2..50a0fd2e7 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -163,7 +163,7 @@ public: m_Amount(a_Amount) { // Initialize all the block types. - for (unsigned long idx = 0; idx < ARRAYCOUNT(m_IsAllowedBelow); ++idx) + for (size_t idx = 0; idx < ARRAYCOUNT(m_IsAllowedBelow); ++idx) { m_IsAllowedBelow[idx] = false; } @@ -175,7 +175,7 @@ public: } // Initialize all the biome types. - for (unsigned long idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx) + for (size_t idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx) { m_IsBiomeAllowed[idx] = false; } -- cgit v1.2.3 From 1d684697186de4340c6a1cc5aea6a14ffd19c002 Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 29 Jul 2014 22:43:25 -0700 Subject: Fixed "Dependency" typos --- src/Bindings/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 2ea2fa8c0..48e7ce79c 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -125,8 +125,8 @@ if (NOT MSVC) DEPENDS ${BINDING_DEPENDENCIES} ) endif () -set_source_files_properties(Bindings/Bindings.cpp PROPERTIES GENERATED TRUE) -set_source_files_properties(Bindings/Bindings.h PROPERTIES GENERATED TRUE) +set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE) +set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE) if(NOT MSVC) add_library(Bindings ${SRCS} ${HDRS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29337cb2e..87599c60d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -151,10 +151,10 @@ if (NOT MSVC) get_directory_property(BINDING_DEPENDENCIES DIRECTORY "Bindings" DEFINITION BINDING_DEPENDENCIES) #clear file - file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt) - foreach(dependecy ${BINDING_DEPENDECIES}) - #write each dependecy on a seperate line - file(APPEND ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt "${dependecy}\n") + file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependencies.txt) + foreach(dependency ${BINDING_DEPENDENCIES}) + #write each dependency on a seperate line + file(APPEND ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependencies.txt "${dependency}\n") endforeach() set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "Bindings.cpp Bindings.h") -- cgit v1.2.3 From 75b7c3775528ced647eb5d7db3437d2856e01e7e Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 13:06:48 +0200 Subject: PreSimulator: Added configurations. You can now choose if it should pregenerate something or not --- src/Generating/ComposableGenerator.cpp | 7 ++++++- src/Generating/FinishGen.cpp | 22 ++++++++++++++++++---- src/Generating/FinishGen.h | 7 ++++++- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index a7659149a..cedb9aeb7 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -408,7 +408,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { - m_FinishGens.push_back(new cFinishGenPreSimulator); + // Load the settings + bool PreSimulateFallingBlocks = a_IniFile.GetValueSetB("Generator", "PreSimulatorFallingBlocks", true); + bool PreSimulateWater = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true); + bool PreSimulateLava = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true); + + m_FinishGens.push_back(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)); } else if (NoCaseCompare(*itr, "RainbowRoads") == 0) { diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index f53addb68..e8324095e 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -555,7 +555,10 @@ void cFinishGenBottomLava::GenFinish(cChunkDesc & a_ChunkDesc) //////////////////////////////////////////////////////////////////////////////// // cFinishGenPreSimulator: -cFinishGenPreSimulator::cFinishGenPreSimulator(void) +cFinishGenPreSimulator::cFinishGenPreSimulator(bool a_PreSimulateFallingBlocks, bool a_PreSimulateWater, bool a_PreSimulateLava) : + m_PreSimulateFallingBlocks(a_PreSimulateFallingBlocks), + m_PreSimulateWater(a_PreSimulateWater), + m_PreSimulateLava(a_PreSimulateLava) { // Nothing needed yet } @@ -566,9 +569,20 @@ cFinishGenPreSimulator::cFinishGenPreSimulator(void) void cFinishGenPreSimulator::GenFinish(cChunkDesc & a_ChunkDesc) { - CollapseSandGravel(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap()); - StationarizeFluid(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap(), E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); - StationarizeFluid(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap(), E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); + if (m_PreSimulateFallingBlocks) + { + CollapseSandGravel(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap()); + } + + if (m_PreSimulateWater) + { + StationarizeFluid(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap(), E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER); + } + + if (m_PreSimulateLava) + { + StationarizeFluid(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap(), E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA); + } // TODO: other operations } diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 50a0fd2e7..4a08d70c8 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -240,9 +240,14 @@ class cFinishGenPreSimulator : public cFinishGen { public: - cFinishGenPreSimulator(void); + cFinishGenPreSimulator(bool a_PreSimulateFallingBlocks, bool a_PreSimulateWater, bool a_PreSimulateLava); protected: + + bool m_PreSimulateFallingBlocks; + bool m_PreSimulateWater; + bool m_PreSimulateLava; + // Drops hanging sand and gravel down to the ground, recalculates heightmap void CollapseSandGravel( cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change -- cgit v1.2.3 From 4dd858f8997488e2252f5a04df9df1654a70d67f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 29 Jul 2014 17:45:55 +0200 Subject: Added a cMojangAPI class for PlayerName -> UUID lookups, with cache. The cache is persisted into a SQLite DB file on server shutdown. --- src/Bindings/ManualBindings.cpp | 2 +- src/CMakeLists.txt | 4 +- src/Protocol/Authenticator.cpp | 216 +------------------ src/Protocol/Authenticator.h | 27 +-- src/Protocol/CMakeLists.txt | 2 + src/Protocol/MojangAPI.cpp | 446 ++++++++++++++++++++++++++++++++++++++++ src/Protocol/MojangAPI.h | 102 +++++++++ src/Root.cpp | 1 + src/Root.h | 3 + 9 files changed, 564 insertions(+), 239 deletions(-) create mode 100644 src/Protocol/MojangAPI.cpp create mode 100644 src/Protocol/MojangAPI.h (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 28ee00b36..6d69e2595 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2189,7 +2189,7 @@ static int tolua_cClientHandle_GetUUIDsFromPlayerNames(lua_State * L) lua_newtable(L); // stack index 3 // Get the UUIDs: - AStringVector UUIDs = cRoot::Get()->GetAuthenticator().GetUUIDsFromPlayerNames(PlayerNames); + AStringVector UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames); if (UUIDs.size() != PlayerNames.size()) { // A hard error has occured while processing the request, no UUIDs were returned. Return an empty table: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29337cb2e..1d1c33088 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,6 +138,8 @@ SET (HDRS XMLParser.h) include_directories(".") +include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/sqlite") +include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/SQLiteCpp/include") if (NOT MSVC) # Bindings need to reference other folders, so they are done here instead @@ -311,4 +313,4 @@ endif () if (WIN32) target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib) endif() -target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua) +target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua SQLiteCpp) diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 75721589f..e5d16cf10 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Authenticator.h" +#include "MojangAPI.h" #include "../Root.h" #include "../Server.h" #include "../ClientHandle.h" @@ -17,76 +18,11 @@ #define DEFAULT_AUTH_SERVER "sessionserver.mojang.com" #define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%" -#define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" -#define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" - -/** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert: -Downloaded from http://certs.starfieldtech.com/repository/ */ -static const AString StarfieldCACert() -{ - return AString( - // G2 cert - "-----BEGIN CERTIFICATE-----\n" - "MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n" - "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" - "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\n" - "ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw\n" - "MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n" - "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\n" - "aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp\n" - "Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" - "ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg\n" - "nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1\n" - "HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N\n" - "Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN\n" - "dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0\n" - "HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\n" - "BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G\n" - "CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU\n" - "sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3\n" - "4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg\n" - "8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\n" - "pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n" - "mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n" - "-----END CERTIFICATE-----\n\n" - // Original (G1) cert: - "-----BEGIN CERTIFICATE-----\n" - "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n" - "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n" - "U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n" - "NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n" - "ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n" - "ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n" - "DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n" - "8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n" - "+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n" - "X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n" - "K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n" - "1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n" - "A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n" - "zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n" - "YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n" - "bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n" - "DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n" - "L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n" - "eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n" - "xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n" - "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n" - "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n" - "-----END CERTIFICATE-----\n" - ); -} - - - - cAuthenticator::cAuthenticator(void) : super("cAuthenticator"), m_Server(DEFAULT_AUTH_SERVER), m_Address(DEFAULT_AUTH_ADDRESS), - m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), - m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_ShouldAuthenticate(true) { } @@ -109,8 +45,6 @@ void cAuthenticator::ReadINI(cIniFile & IniFile) m_Server = IniFile.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER); m_Address = IniFile.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS); m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true); - m_NameToUUIDServer = IniFile.GetValueSet ("Authentication", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); - m_NameToUUIDAddress = IniFile.GetValueSet ("Authentication", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); } @@ -157,93 +91,6 @@ void cAuthenticator::Stop(void) -AStringVector cAuthenticator::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames) -{ - AStringVector res; - - // Create the request body - a JSON containing all the playernames: - Json::Value root; - for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) - { - Json::Value req(*itr); - root.append(req); - } // for itr - a_PlayerNames[] - Json::FastWriter Writer; - AString RequestBody = Writer.write(root); - - // Create the HTTP request: - AString Request; - Request += "POST " + m_NameToUUIDAddress + " HTTP/1.1\r\n"; - Request += "Host: " + m_NameToUUIDServer + "\r\n"; - Request += "User-Agent: MCServer\r\n"; - Request += "Connection: close\r\n"; - Request += "Content-Type: application/json\r\n"; - Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); - Request += "\r\n"; - Request += RequestBody; - - // Get the response from the server: - AString Response; - if (!SecureGetFromAddress(StarfieldCACert(), m_NameToUUIDServer, Request, Response)) - { - return res; - } - - // Check the HTTP status line: - const AString Prefix("HTTP/1.1 200 OK"); - AString HexDump; - if (Response.compare(0, Prefix.size(), Prefix)) - { - LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); - LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); - return res; - } - - // Erase the HTTP headers from the response: - size_t idxHeadersEnd = Response.find("\r\n\r\n"); - if (idxHeadersEnd == AString::npos) - { - LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); - LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); - return res; - } - Response.erase(0, idxHeadersEnd + 4); - - // Parse the returned string into Json: - Json::Reader reader; - if (!reader.parse(Response, root, false) || !root.isArray()) - { - LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); - LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); - return res; - } - - // Fill in the resulting array; do not expect to get the UUIDs in the same order as the inputs: - size_t len = a_PlayerNames.size(); - size_t JsonCount = root.size(); - res.resize(len); - for (size_t idx = 0; idx < len; idx++) // For each input username... - { - const AString & InputName = a_PlayerNames[idx]; - for (size_t IdxJson = 0; IdxJson < JsonCount; ++IdxJson) - { - Json::Value & Val = root[IdxJson]; - AString JsonName = Val.get("name", "").asString(); - if (NoCaseCompare(JsonName, InputName) == 0) - { - res[idx] = Val.get("id", "").asString(); - break; - } - } // for IdxJson - root[] - } // for idx - a_PlayerNames[] / res[] - - return res; -} - - - - - void cAuthenticator::Execute(void) { for (;;) @@ -286,62 +133,6 @@ void cAuthenticator::Execute(void) -bool cAuthenticator::SecureGetFromAddress(const AString & a_CACerts, const AString & a_ExpectedPeerName, const AString & a_Data, AString & a_Response) -{ - // Connect the socket: - cBlockingSslClientSocket Socket; - Socket.SetTrustedRootCertsFromString(a_CACerts, a_ExpectedPeerName); - if (!Socket.Connect(a_ExpectedPeerName, 443)) - { - LOGWARNING("cAuthenticator: Can't connect to %s: %s", a_ExpectedPeerName.c_str(), Socket.GetLastErrorText().c_str()); - return false; - } - - if (!Socket.Send(a_Data.c_str(), a_Data.size())) - { - LOGWARNING("cAuthenticator: Writing SSL data failed: %s", Socket.GetLastErrorText().c_str()); - return false; - } - - // Read the HTTP response: - int ret; - unsigned char buf[1024]; - - for (;;) - { - ret = Socket.Receive(buf, sizeof(buf)); - - if ((ret == POLARSSL_ERR_NET_WANT_READ) || (ret == POLARSSL_ERR_NET_WANT_WRITE)) - { - // This value should never be returned, it is handled internally by cBlockingSslClientSocket - LOGWARNING("cAuthenticator: SSL reading failed internally"); - return false; - } - if (ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) - { - break; - } - if (ret < 0) - { - LOGWARNING("cAuthenticator: SSL reading failed: -0x%x", -ret); - return false; - } - if (ret == 0) - { - break; - } - - a_Response.append((const char *)buf, (size_t)ret); - } - - Socket.Disconnect(); - return true; -} - - - - - bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties) { LOGD("Trying to authenticate user %s", a_UserName.c_str()); @@ -359,7 +150,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S Request += "\r\n"; AString Response; - if (!SecureGetFromAddress(StarfieldCACert(), m_Server, Request, Response)) + if (!cMojangAPI::SecureRequest(m_Server, Request, Response)) { return false; } @@ -399,6 +190,9 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S a_UserName = root.get("name", "Unknown").asString(); a_UUID = root.get("id", "").asString(); a_Properties = root["properties"]; + + // Store the player's UUID in the NameToUUID map in MojangAPI: + cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(a_UserName, a_UUID); // If the UUID doesn't contain the dashes, insert them at the proper places: if (a_UUID.size() == 32) diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 82ecb1f7a..853eff535 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -11,8 +11,6 @@ #pragma once -#ifndef CAUTHENTICATOR_H_INCLUDED -#define CAUTHENTICATOR_H_INCLUDED #include "../OSSupport/IsThread.h" @@ -53,12 +51,6 @@ public: /** Stops the authenticator thread. The thread may be started and stopped repeatedly */ void Stop(void); - /** Converts the player names into UUIDs. - a_PlayerName[idx] will be converted to UUID and returned as idx-th value - The UUID will be empty on error. - Blocking operation, do not use in world-tick thread! */ - AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName); - private: class cUser @@ -91,34 +83,17 @@ private: For example "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%". */ AString m_Address; - /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */ - AString m_NameToUUIDServer; - - /** The URL to use for converting player names to UUIDs, without server part. - For example "/profiles/page/1". */ - AString m_NameToUUIDAddress; - AString m_PropertiesAddress; bool m_ShouldAuthenticate; /** cIsThread override: */ virtual void Execute(void) override; - /** Connects to a hostname using SSL, sends given data, and sets the response, returning whether all was successful or not */ - bool SecureGetFromAddress(const AString & a_CACerts, const AString & a_ExpectedPeerName, const AString & a_Request, AString & a_Response); - /** Returns true if the user authenticated okay, false on error - Sets the username, UUID, and properties (i.e. skin) fields - */ + Returns the case-corrected username, UUID, and properties (eg. skin). */ bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties); }; - -#endif // CAUTHENTICATOR_H_INCLUDED - - - - diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt index ae447ce54..1ba66ff1f 100644 --- a/src/Protocol/CMakeLists.txt +++ b/src/Protocol/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories ("${PROJECT_SOURCE_DIR}/../") SET (SRCS Authenticator.cpp ChunkDataSerializer.cpp + MojangAPI.cpp Protocol125.cpp Protocol132.cpp Protocol14x.cpp @@ -18,6 +19,7 @@ SET (SRCS SET (HDRS Authenticator.h ChunkDataSerializer.h + MojangAPI.h Protocol.h Protocol125.h Protocol132.h diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp new file mode 100644 index 000000000..05f9c09a7 --- /dev/null +++ b/src/Protocol/MojangAPI.cpp @@ -0,0 +1,446 @@ + +// MojangAPI.cpp + +// Implements the cMojangAPI class representing the various API points provided by Mojang's webservices, and a cache for their results + +#include "Globals.h" +#include "MojangAPI.h" +#include "SQLiteCpp/Database.h" +#include "SQLiteCpp/Statement.h" +#include "inifile/iniFile.h" +#include "json/json.h" +#include "PolarSSL++/BlockingSslClientSocket.h" + + + + + +/** The maximum age for items to be kept in the cache. Any item older than this will be removed. */ +const Int64 MAX_AGE = 7 * 24 * 60 * 60; // 7 days ago + + + + + +#define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" +#define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" + + + + + +/** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert: +Downloaded from http://certs.starfieldtech.com/repository/ */ +static const AString & StarfieldCACert(void) +{ + static const AString Cert( + // G2 cert + "-----BEGIN CERTIFICATE-----\n" + "MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n" + "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" + "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\n" + "ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw\n" + "MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n" + "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\n" + "aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp\n" + "Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg\n" + "nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1\n" + "HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N\n" + "Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN\n" + "dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0\n" + "HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\n" + "BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G\n" + "CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU\n" + "sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3\n" + "4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg\n" + "8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\n" + "pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n" + "mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n" + "-----END CERTIFICATE-----\n\n" + // Original (G1) cert: + "-----BEGIN CERTIFICATE-----\n" + "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n" + "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n" + "U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n" + "NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n" + "ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n" + "ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n" + "DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n" + "8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n" + "+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n" + "X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n" + "K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n" + "1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n" + "A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n" + "zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n" + "YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n" + "bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n" + "DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n" + "L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n" + "eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n" + "xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n" + "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n" + "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n" + "-----END CERTIFICATE-----\n" + ); + + return Cert; +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cMojangAPI: + +cMojangAPI::cMojangAPI(void) : + m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), + m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS) +{ +} + + + + + +cMojangAPI::~cMojangAPI() +{ + SaveCachesToDisk(); +} + + + + + +void cMojangAPI::Start(cIniFile & a_SettingsIni) +{ + m_NameToUUIDServer = a_SettingsIni.GetValueSet("Authentication", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); + m_NameToUUIDAddress = a_SettingsIni.GetValueSet("Authentication", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); + LoadCachesFromDisk(); +} + + + + + +AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames) +{ + // Convert all playernames to lowercase: + AStringVector PlayerNames; + for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) + { + AString Lower(*itr); + PlayerNames.push_back(StrToLower(Lower)); + } // for itr - a_PlayerNames[] + + // Request the cache to populate any names not yet contained: + CacheNamesToUUIDs(PlayerNames); + + // Retrieve from cache: + size_t idx = 0; + AStringVector res; + res.resize(PlayerNames.size()); + cCSLock Lock(m_CSNameToUUID); + for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx) + { + cNameToUUIDMap::const_iterator itrN = m_NameToUUID.find(*itr); + if (itrN != m_NameToUUID.end()) + { + res[idx] = itrN->second.m_UUID; + } + } // for itr - PlayerNames[] + return res; +} + + + + + +void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID) +{ + AString lcName(a_PlayerName); + Int64 Now = time(NULL); + cCSLock Lock(m_CSNameToUUID); + m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(a_PlayerName, a_UUID, Now); +} + + + + + +bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response) +{ + // Connect the socket: + cBlockingSslClientSocket Socket; + Socket.SetTrustedRootCertsFromString(StarfieldCACert(), a_ServerName); + if (!Socket.Connect(a_ServerName, 443)) + { + LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str()); + return false; + } + + if (!Socket.Send(a_Request.c_str(), a_Request.size())) + { + LOGWARNING("%s: Writing SSL data failed: %s", __FUNCTION__, Socket.GetLastErrorText().c_str()); + return false; + } + + // Read the HTTP response: + int ret; + unsigned char buf[1024]; + + for (;;) + { + ret = Socket.Receive(buf, sizeof(buf)); + + if ((ret == POLARSSL_ERR_NET_WANT_READ) || (ret == POLARSSL_ERR_NET_WANT_WRITE)) + { + // This value should never be returned, it is handled internally by cBlockingSslClientSocket + LOGWARNING("%s: SSL reading failed internally", __FUNCTION__); + return false; + } + if (ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) + { + break; + } + if (ret < 0) + { + LOGWARNING("%s: SSL reading failed: -0x%x", __FUNCTION__, -ret); + return false; + } + if (ret == 0) + { + break; + } + + a_Response.append((const char *)buf, (size_t)ret); + } + + Socket.Disconnect(); + return true; +} + + + + + +AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) +{ + switch (a_UUID.size()) + { + case 32: return a_UUID; + + case 36: + { + AString res; + // TODO + return res; + } + } + LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str()); + return ""; +} + + + + + +AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) +{ + switch (a_UUID.size()) + { + case 36: return a_UUID; + + case 32: + { + AString res; + // TODO + return res; + } + } + LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str()); + return ""; +} + + + + + +void cMojangAPI::LoadCachesFromDisk(void) +{ + try + { + // Open up the SQLite DB: + SQLite::Database db("NameToUUID.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); + + // Clean up old entries: + { + SQLite::Statement stmt(db, "DELETE FROM PlayerNameToUUID WHERE DateTime < ?"); + Int64 LimitDateTime = time(NULL) - MAX_AGE; + stmt.bind(1, LimitDateTime); + stmt.exec(); + } + + // Retrieve all remaining entries:: + SQLite::Statement stmt(db, "SELECT PlayerName, UUID, DateTime FROM PlayerNameToUUID"); + while (stmt.executeStep()) + { + AString PlayerName = stmt.getColumn(0); + AString UUID = stmt.getColumn(1); + Int64 DateTime = stmt.getColumn(2); + AString lcPlayerName = PlayerName; + m_NameToUUID[StrToLower(lcPlayerName)] = sUUIDRecord(PlayerName, UUID, DateTime); + } + } + catch (const SQLite::Exception & ex) + { + LOGINFO("Loading MojangAPI cache failed: %s", ex.what()); + } +} + + + + + +void cMojangAPI::SaveCachesToDisk(void) +{ + try + { + // Open up the SQLite DB: + SQLite::Database db("NameToUUID.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); + + // Remove all entries: + db.exec("DELETE FROM PlayerNameToUUID"); + + // Save all cache entries: + SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)"); + Int64 LimitDateTime = time(NULL) - MAX_AGE; + cCSLock Lock(m_CSNameToUUID); + for (cNameToUUIDMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr) + { + if (itr->second.m_DateTime < LimitDateTime) + { + // This item is too old, do not save + continue; + } + stmt.bind(1, itr->second.m_PlayerName); + stmt.bind(2, itr->second.m_UUID); + stmt.bind(3, itr->second.m_DateTime); + stmt.exec(); + stmt.reset(); + } + } + catch (const SQLite::Exception & ex) + { + LOGINFO("Saving MojangAPI cache failed: %s", ex.what()); + } +} + + + + + +void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) +{ + // Create a list of names to query, by removing those that are already cached: + AStringVector NamesToQuery; + NamesToQuery.reserve(a_PlayerNames.size()); + { + cCSLock Lock(m_CSNameToUUID); + for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) + { + if (m_NameToUUID.find(*itr) == m_NameToUUID.end()) + { + NamesToQuery.push_back(*itr); + } + } // for itr - a_PlayerNames[] + } // Lock(m_CSNameToUUID) + + while (!NamesToQuery.empty()) + { + // Create the request body - a JSON containing up to 100 playernames: + Json::Value root; + int Count = 0; + AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); + for (; (itr != end) && (Count < 100); ++itr, ++Count) + { + Json::Value req(*itr); + root.append(req); + } // for itr - a_PlayerNames[] + NamesToQuery.erase(NamesToQuery.begin(), itr); + Json::FastWriter Writer; + AString RequestBody = Writer.write(root); + + // Create the HTTP request: + AString Request; + Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; + Request += "Host: " + m_NameToUUIDServer + "\r\n"; + Request += "User-Agent: MCServer\r\n"; + Request += "Connection: close\r\n"; + Request += "Content-Type: application/json\r\n"; + Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); + Request += "\r\n"; + Request += RequestBody; + + // Get the response from the server: + AString Response; + if (!SecureRequest(m_NameToUUIDServer, Request, Response)) + { + continue; + } + + // Check the HTTP status line: + const AString Prefix("HTTP/1.1 200 OK"); + AString HexDump; + if (Response.compare(0, Prefix.size(), Prefix)) + { + LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + continue; + } + + // Erase the HTTP headers from the response: + size_t idxHeadersEnd = Response.find("\r\n\r\n"); + if (idxHeadersEnd == AString::npos) + { + LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + continue; + } + Response.erase(0, idxHeadersEnd + 4); + + // Parse the returned string into Json: + Json::Reader reader; + if (!reader.parse(Response, root, false) || !root.isArray()) + { + LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); + LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + continue; + } + + // Store the returned results into cache: + size_t JsonCount = root.size(); + Int64 Now = time(NULL); + cCSLock Lock(m_CSNameToUUID); + for (size_t idx = 0; idx < JsonCount; ++idx) + { + Json::Value & Val = root[idx]; + AString JsonName = Val.get("name", "").asString(); + AString JsonUUID = Val.get("id", "").asString(); + if (JsonUUID.empty()) + { + continue; + } + AString lcName = JsonName; + m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(JsonName, JsonUUID, Now); + } // for idx - root[] + } // while (!NamesToQuery.empty()) +} + + + + diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h new file mode 100644 index 000000000..789fdf818 --- /dev/null +++ b/src/Protocol/MojangAPI.h @@ -0,0 +1,102 @@ + +// MojangAPI.h + +// Declares the cMojangAPI class representing the various API points provided by Mojang's webservices, and a cache for their results + + + + + +#pragma once + +#include + + + + + +class cMojangAPI +{ +public: + cMojangAPI(void); + ~cMojangAPI(); + + /** Initializes the API; reads the settings from the specified ini file. + Loads cached results from disk. */ + void Start(cIniFile & a_SettingsIni); + + /** Connects to the specified server using SSL, sends the given request and receives the response. + Checks Mojang certificates using the hard-coded Starfield root CA certificate. + Returns true if all was successful, false on failure. */ + static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response); + + /** Converts the given UUID to its short form (32 bytes, no dashes). + Logs a warning and returns empty string if not a UUID. */ + static AString MakeUUIDShort(const AString & a_UUID); + + /** Converts the given UUID to its dashed form (36 bytes, 4 dashes). + Logs a warning and returns empty string if not a UUID. */ + static AString MakeUUIDDashed(const AString & a_UUID); + + /** Converts the player names into UUIDs. + a_PlayerName[idx] will be converted to UUID and returned as idx-th value + The UUID will be empty on error. + Blocking operation, do not use in world-tick thread! */ + AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName); + + /** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from + authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime + stamp to now. */ + void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID); + +protected: + struct sUUIDRecord + { + AString m_PlayerName; // Case-correct playername + AString m_UUID; + Int64 m_DateTime; // UNIXtime of the UUID lookup + + sUUIDRecord(void) : + m_UUID(), + m_DateTime(time(NULL)) + { + } + + sUUIDRecord(const AString & a_PlayerName, const AString & a_UUID, Int64 a_DateTime) : + m_PlayerName(a_PlayerName), + m_UUID(a_UUID), + m_DateTime(a_DateTime) + { + } + }; + typedef std::map cNameToUUIDMap; // maps Lowercased PlayerName to sUUIDRecord + + /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */ + AString m_NameToUUIDServer; + + /** The URL to use for converting player names to UUIDs, without server part. + For example "/profiles/page/1". */ + AString m_NameToUUIDAddress; + + /** Cache for the Name-to-UUID lookups. The map key is expected lowercased. Protected by m_CSNameToUUID. */ + cNameToUUIDMap m_NameToUUID; + + /** Protects m_NameToUUID against simultaneous multi-threaded access. */ + cCriticalSection m_CSNameToUUID; + + + /** Loads the caches from a disk storage. */ + void LoadCachesFromDisk(void); + + /** Saves the caches to a disk storage. */ + void SaveCachesToDisk(void); + + /** Makes sure all specified names are in the cache. Downloads any missing ones from Mojang API servers. + Names that are not valid are not added into the cache. + ASSUMEs that a_PlayerNames contains lowercased player names. */ + void CacheNamesToUUIDs(const AStringVector & a_PlayerNames); +} ; + + + + diff --git a/src/Root.cpp b/src/Root.cpp index b03a13382..7d4fb80fd 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -145,6 +145,7 @@ void cRoot::Start(void) } LOG("Starting server..."); + m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init if (!m_Server->InitServer(IniFile)) { LOGERROR("Failure starting server, aborting..."); diff --git a/src/Root.h b/src/Root.h index 08aafe3c9..92a60a10d 100644 --- a/src/Root.h +++ b/src/Root.h @@ -2,6 +2,7 @@ #pragma once #include "Protocol/Authenticator.h" +#include "Protocol/MojangAPI.h" #include "HTTPServer/HTTPServer.h" #include "Defines.h" @@ -78,6 +79,7 @@ public: cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } + cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread @@ -182,6 +184,7 @@ private: cWebAdmin * m_WebAdmin; cPluginManager * m_PluginManager; cAuthenticator m_Authenticator; + cMojangAPI m_MojangAPI; cHTTPServer m_HTTPServer; cMCLogger * m_Log; -- cgit v1.2.3 From 6476bd0e2ee7e128e3eaa56159f169f0a53736ff Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 13:44:03 +0200 Subject: Exported cMojangAPI to Lua. --- src/Bindings/AllToLua.pkg | 1 + src/Bindings/ManualBindings.cpp | 9 ++++++--- src/Protocol/MojangAPI.h | 13 ++++++++++++- src/Root.h | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 1e5dfd2fe..d3e3f5b45 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -77,6 +77,7 @@ $cfile "../Map.h" $cfile "../MapManager.h" $cfile "../Scoreboard.h" $cfile "../Statistics.h" +$cfile "../Protocol/MojangAPI.h" diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 6d69e2595..026a6bad5 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2157,11 +2157,11 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L) -static int tolua_cClientHandle_GetUUIDsFromPlayerNames(lua_State * L) +static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) { cLuaState S(L); if ( - !S.CheckParamUserTable(1, "cClientHandle") || + !S.CheckParamUserTable(1, "cMojangAPI") || !S.CheckParamTable(2) || !S.CheckParamEnd(3) ) @@ -3144,9 +3144,12 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage); - tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cClientHandle_GetUUIDsFromPlayerNames); tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cMojangAPI"); + tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cMojangAPI_GetUUIDsFromPlayerNames); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cItemGrid"); tolua_function(tolua_S, "GetSlotCoords", Lua_ItemGrid_GetSlotCoords); tolua_endmodule(tolua_S); diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 789fdf818..cc2902a19 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -15,9 +15,12 @@ +// tolua_begin class cMojangAPI { public: + // tolua_end + cMojangAPI(void); ~cMojangAPI(); @@ -30,6 +33,8 @@ public: Returns true if all was successful, false on failure. */ static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response); + // tolua_begin + /** Converts the given UUID to its short form (32 bytes, no dashes). Logs a warning and returns empty string if not a UUID. */ static AString MakeUUIDShort(const AString & a_UUID); @@ -38,16 +43,22 @@ public: Logs a warning and returns empty string if not a UUID. */ static AString MakeUUIDDashed(const AString & a_UUID); + // tolua_end + /** Converts the player names into UUIDs. a_PlayerName[idx] will be converted to UUID and returned as idx-th value The UUID will be empty on error. Blocking operation, do not use in world-tick thread! */ AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName); + // tolua_begin + /** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime stamp to now. */ void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID); + + // tolua_end protected: struct sUUIDRecord @@ -95,7 +106,7 @@ protected: Names that are not valid are not added into the cache. ASSUMEs that a_PlayerNames contains lowercased player names. */ void CacheNamesToUUIDs(const AStringVector & a_PlayerNames); -} ; +} ; // tolua_export diff --git a/src/Root.h b/src/Root.h index 92a60a10d..210c36ea9 100644 --- a/src/Root.h +++ b/src/Root.h @@ -79,7 +79,7 @@ public: cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } - cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } + cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } // tolua_export /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread -- cgit v1.2.3 From 17a94b16ea6207fd5f38fbd309b4db0d92de0d31 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 13:52:51 +0200 Subject: MojangAPI: Implemented UUID shortening and dashing. --- src/ClientHandle.cpp | 3 ++- src/ClientHandle.h | 8 +++++++- src/Protocol/Authenticator.cpp | 11 +---------- src/Protocol/MojangAPI.cpp | 34 +++++++++++++++++++++++++++------- src/Protocol/Protocol17x.cpp | 6 +++--- 5 files changed, 40 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e4ad218a2..3f81f0a29 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -233,13 +233,14 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) // This guarantees that they will never collide with an online UUID and can be distinguished. // Proper format for a version 3 UUID is: // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B + // Note that we generate a short UUID (without the dashes) // Generate an md5 checksum, and use it as base for the ID: unsigned char MD5[16]; md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); MD5[6] &= 0x0f; // Need to trim to 4 bits only... MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars - return Printf("%02x%02x%02x%02x-%02x%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x", + return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x", MD5[0], MD5[1], MD5[2], MD5[3], MD5[4], MD5[5], MD5[6], MD5[7], MD5[8], MD5[9], MD5[10], MD5[11], diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 50ed596d5..f2183a5ca 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -66,7 +66,9 @@ public: cPlayer * GetPlayer(void) { return m_Player; } // tolua_export + /** Returns the player's UUID, as used by the protocol, in the short form (no dashes) */ const AString & GetUUID(void) const { return m_UUID; } // tolua_export + void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; } const Json::Value & GetProperties(void) const { return m_Properties; } @@ -80,7 +82,7 @@ public: /** Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. - Returns a 36-char UUID (with dashes). */ + Returns a 32-char UUID (no dashes). */ static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export /** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. @@ -360,7 +362,11 @@ private: int m_NumBlockChangeInteractionsThisTick; static int s_ClientCount; + + /** ID used for identification during authenticating. Assigned sequentially for each new instance. */ int m_UniqueID; + + /** Contains the UUID used by Mojang to identify the player's account. Short UUID stored here (without dashes) */ AString m_UUID; /** Set to true when the chunk where the player is is sent to the client. Used for spawning the player */ diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index e5d16cf10..160564d51 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -188,21 +188,12 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S return false; } a_UserName = root.get("name", "Unknown").asString(); - a_UUID = root.get("id", "").asString(); + a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString()); a_Properties = root["properties"]; // Store the player's UUID in the NameToUUID map in MojangAPI: cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(a_UserName, a_UUID); - // If the UUID doesn't contain the dashes, insert them at the proper places: - if (a_UUID.size() == 32) - { - a_UUID.insert(8, "-"); - a_UUID.insert(13, "-"); - a_UUID.insert(18, "-"); - a_UUID.insert(23, "-"); - } - return true; } diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 05f9c09a7..52afd71da 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -18,6 +18,9 @@ /** The maximum age for items to be kept in the cache. Any item older than this will be removed. */ const Int64 MAX_AGE = 7 * 24 * 60 * 60; // 7 days ago +/** The maximum number of names to send in a single query */ +const int MAX_PER_QUERY = 100; + @@ -29,6 +32,7 @@ const Int64 MAX_AGE = 7 * 24 * 60 * 60; // 7 days ago + /** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert: Downloaded from http://certs.starfieldtech.com/repository/ */ static const AString & StarfieldCACert(void) @@ -161,9 +165,10 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID) { AString lcName(a_PlayerName); + AString UUID = MakeUUIDShort(a_UUID); Int64 Now = time(NULL); cCSLock Lock(m_CSNameToUUID); - m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(a_PlayerName, a_UUID, Now); + m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(a_PlayerName, UUID, Now); } @@ -234,8 +239,14 @@ AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) case 36: { + // Remove the dashes from the string: AString res; - // TODO + res.reserve(32); + res.append(a_UUID, 0, 8); + res.append(a_UUID, 9, 4); + res.append(a_UUID, 14, 4); + res.append(a_UUID, 19, 4); + res.append(a_UUID, 24, 12); return res; } } @@ -256,7 +267,16 @@ AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) case 32: { AString res; - // TODO + res.reserve(36); + res.append(a_UUID, 0, 8); + res.push_back('-'); + res.append(a_UUID, 8, 4); + res.push_back('-'); + res.append(a_UUID, 12, 4); + res.push_back('-'); + res.append(a_UUID, 16, 4); + res.push_back('-'); + res.append(a_UUID, 20, 12); return res; } } @@ -362,11 +382,11 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) while (!NamesToQuery.empty()) { - // Create the request body - a JSON containing up to 100 playernames: + // Create the request body - a JSON containing up to MAX_PER_QUERY playernames: Json::Value root; int Count = 0; AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); - for (; (itr != end) && (Count < 100); ++itr, ++Count) + for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count) { Json::Value req(*itr); root.append(req); @@ -377,7 +397,7 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) // Create the HTTP request: AString Request; - Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; + Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_NameToUUIDServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; @@ -430,7 +450,7 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); - AString JsonUUID = Val.get("id", "").asString(); + AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index dadf82716..73aba167d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -680,7 +680,7 @@ void cProtocol172::SendLoginSuccess(void) { cPacketizer Pkt(*this, 0x02); // Login success packet - Pkt.WriteString(m_Client->GetUUID()); + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); Pkt.WriteString(m_Client->GetUsername()); } @@ -941,7 +941,7 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); - Pkt.WriteString(a_Player.GetClientHandle()->GetUUID()); + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); Pkt.WriteString(a_Player.GetName()); Pkt.WriteFPInt(a_Player.GetPosX()); Pkt.WriteFPInt(a_Player.GetPosY()); @@ -3014,7 +3014,7 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); - Pkt.WriteString(a_Player.GetClientHandle()->GetUUID()); + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); Pkt.WriteString(a_Player.GetName()); const Json::Value & Properties = m_Client->GetProperties(); -- cgit v1.2.3 From 5daeba7e887ecf15b2facd3801f424a5bfcaa2e6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 13:59:47 +0200 Subject: Removed lighting code in cEnderman::CheckEventSeePlayer --- src/Mobs/Enderman.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 6b7a22757..9c1cb7ce3 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -116,15 +116,7 @@ void cEnderman::CheckEventSeePlayer() ASSERT(Callback.GetPlayer() != NULL); - int CX, CZ; - cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, CX, CZ); - if (!GetWorld()->IsChunkLighted(CX, CZ)) - { - GetWorld()->QueueLightChunk(CX, CZ); - return; - } - - if ((GetWorld()->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() < 15) && !Callback.GetPlayer()->IsGameModeCreative()) + if (!Callback.GetPlayer()->IsGameModeCreative()) { super::EventSeePlayer(Callback.GetPlayer()); m_EMState = CHASING; -- cgit v1.2.3 From 426773df17dbd7748b51021a27119240de5b1922 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 14:03:14 +0200 Subject: ManualBindings: Fixed alignment. --- src/Bindings/ManualBindings.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 026a6bad5..b1d302560 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3141,9 +3141,9 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cClientHandle"); - tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); - tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); - tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage); + tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); + tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); + tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cMojangAPI"); -- cgit v1.2.3 From 85d64d291a6d11df6689190268c1f4c6b1c02cdd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 14:09:30 +0200 Subject: MojangAPI: Clarified the UUID conversion code. --- src/Protocol/MojangAPI.cpp | 15 +++++++++++++-- src/Protocol/MojangAPI.h | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 52afd71da..86ff134db 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -233,9 +233,14 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) { + // Note: we only check the string's length, not the actual content switch (a_UUID.size()) { - case 32: return a_UUID; + case 32: + { + // Already is a short UUID + return a_UUID; + } case 36: { @@ -260,12 +265,18 @@ AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) { + // Note: we only check the string's length, not the actual content switch (a_UUID.size()) { - case 36: return a_UUID; + case 36: + { + // Already is a dashed UUID + return a_UUID; + } case 32: { + // Insert dashes at the proper positions: AString res; res.reserve(36); res.append(a_UUID, 0, 8); diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index cc2902a19..c99f940ad 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -36,11 +36,13 @@ public: // tolua_begin /** Converts the given UUID to its short form (32 bytes, no dashes). - Logs a warning and returns empty string if not a UUID. */ + Logs a warning and returns empty string if not a UUID. + Note: only checks the string's length, not the actual content. */ static AString MakeUUIDShort(const AString & a_UUID); /** Converts the given UUID to its dashed form (36 bytes, 4 dashes). - Logs a warning and returns empty string if not a UUID. */ + Logs a warning and returns empty string if not a UUID. + Note: only checks the string's length, not the actual content. */ static AString MakeUUIDDashed(const AString & a_UUID); // tolua_end -- cgit v1.2.3 From 5249f574bd077158836455fa66218e5fea6dcafe Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 15:55:50 +0200 Subject: Added RoofedForest trees. Could still be improved allot. --- src/Generating/Trees.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++-- src/Generating/Trees.h | 2 ++ 2 files changed, 73 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index c40322630..87405608b 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -218,7 +218,6 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No return; } - case biRoofedForest: case biColdTaiga: case biColdTaigaHills: case biMegaTaiga: @@ -238,7 +237,6 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No case biIcePlainsSpikes: case biJungleM: case biJungleEdgeM: - case biRoofedForestM: case biColdTaigaM: case biMegaSpruceTaiga: case biMegaSpruceTaigaHills: @@ -253,6 +251,13 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } + + case biRoofedForest: + case biRoofedForestM: + { + GetRoofedForestTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); + return; + } case biDesert: case biDesertHills: @@ -807,3 +812,67 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & + +void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) +{ + // Calculate a height + int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 4; + + // Creat the trunk + for (int i = 0; i < Height; i++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + } + + // Create branches + for (int i = 0; i < 3; i++) + { + //int x = (a_Noise.IntNoise3D(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) < 0 ? -1 : 2); + //int z = (a_Noise.IntNoise3D(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) < 0 ? -1 : 2); + int x = (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) % 3) - 1; + int z = (a_Noise.IntNoise3DInt(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) % 3) - 1; + + // The branches would end up in the trunk. + if ((x >= a_BlockX) && (x <= a_BlockX + 1) && (z >= a_BlockZ) && (z <= a_BlockZ + 1)) + { + NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z); + if (Val1 < 0) + { + x = a_BlockX + (Val1 < -0.5) ? -1 : 3; + } + else + { + z = a_BlockZ + (Val1 < 0.5) ? -1 : 3; + } + } + + int y = Height - (a_Noise.IntNoise3DInt(a_BlockX + x, a_BlockY * i, a_BlockZ - z) % (Height - (Height / 4))); + + for (int Y = y; Y < Height; Y++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX + x, a_BlockY + Y, a_BlockZ + z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + } + } + + int hei = a_BlockY + Height - 2; + + // The lower two leaves layers are BigO4 with log in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + hei++; + } // for i - 2* + + // The top leaves layer is a BigO3 with leaves in the middle and possibly corners: + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD)); +} + + + + diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index 1f6ac4dff..2b2e0acc3 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -96,6 +96,8 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & /// Generates an image of a small jungle tree (1x1 trunk) void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); +/// Generates an image of a roofed tree forest tree +void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); -- cgit v1.2.3 From 17b679f355b8a63175815418983662c17ee13686 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 17:09:00 +0200 Subject: Fixed compiling using Clang --- src/Generating/Trees.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 87405608b..fb46a5e3b 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -830,8 +830,6 @@ void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & // Create branches for (int i = 0; i < 3; i++) { - //int x = (a_Noise.IntNoise3D(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) < 0 ? -1 : 2); - //int z = (a_Noise.IntNoise3D(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) < 0 ? -1 : 2); int x = (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) % 3) - 1; int z = (a_Noise.IntNoise3DInt(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) % 3) - 1; @@ -841,11 +839,11 @@ void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z); if (Val1 < 0) { - x = a_BlockX + (Val1 < -0.5) ? -1 : 3; + x = a_BlockX + ((Val1 < -0.5) ? -1 : 3); } else { - z = a_BlockZ + (Val1 < 0.5) ? -1 : 3; + z = a_BlockZ + ((Val1 < 0.5) ? -1 : 3); } } -- cgit v1.2.3 From 0336e12cee0a784b076b5f9423bce2b9f803d1c8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 30 Jul 2014 17:09:41 +0200 Subject: MojangAPI: Renamed cache file to MojangAPI.sqlite. --- src/Protocol/MojangAPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 86ff134db..5fbc5b476 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -304,7 +304,7 @@ void cMojangAPI::LoadCachesFromDisk(void) try { // Open up the SQLite DB: - SQLite::Database db("NameToUUID.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + SQLite::Database db("MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); // Clean up old entries: @@ -341,7 +341,7 @@ void cMojangAPI::SaveCachesToDisk(void) try { // Open up the SQLite DB: - SQLite::Database db("NameToUUID.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + SQLite::Database db("MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); // Remove all entries: -- cgit v1.2.3 From c4e6a1423506c253974c7512a4b9b854a1e41b54 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 19:18:11 +0200 Subject: Added lighting code and added comments --- src/Mobs/Enderman.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 9c1cb7ce3..f1f366d3b 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -116,6 +116,23 @@ void cEnderman::CheckEventSeePlayer() ASSERT(Callback.GetPlayer() != NULL); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); + + // Check if the chunk the enderman is in is lit. + if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) + { + m_World->QueueLightChunk(ChunkX, ChunkZ); + return; + } + + // Enderman only attack if the skylight is higher than 6 + if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) <= 7) + { + // TODO: Teleport the enderman to a random spot. + return; + } + if (!Callback.GetPlayer()->IsGameModeCreative()) { super::EventSeePlayer(Callback.GetPlayer()); -- cgit v1.2.3 From fd2d338a252a4c230e54e25a8695d7084a924bbe Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 21:42:48 +0200 Subject: Fixed comment at the end of a for-loop --- src/Generating/Trees.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index fb46a5e3b..308947ad0 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -863,7 +863,7 @@ void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); hei++; - } // for i - 2* + } // for i < 2 // The top leaves layer is a BigO3 with leaves in the middle and possibly corners: PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); -- cgit v1.2.3 From f232ef5cd606d31068a758b3e784f33ca1860af0 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 21:50:02 +0200 Subject: Fixed doxy comment --- src/Generating/Trees.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index 2b2e0acc3..2c54fce82 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -96,7 +96,7 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & /// Generates an image of a small jungle tree (1x1 trunk) void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); -/// Generates an image of a roofed tree forest tree +/// Generates an image of a roofed forest tree void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); -- cgit v1.2.3 From 6e0a8d393bafd0b018f168c4ef7a651a2955c1e8 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 21:56:33 +0200 Subject: Moved GetRoofedForestTreeImage content to GetDarkoakTreeImage --- src/Generating/Trees.cpp | 119 ++++++++++++++++++++++------------------------- src/Generating/Trees.h | 2 - 2 files changed, 55 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 308947ad0..4786cad5a 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -255,7 +255,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No case biRoofedForest: case biRoofedForestM: { - GetRoofedForestTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); + GetDarkoakTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } @@ -412,7 +412,60 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { - // TODO + // Calculate a height + int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 4; + + // Creat the trunk + for (int i = 0; i < Height; i++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + } + + // Create branches + for (int i = 0; i < 3; i++) + { + int x = (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) % 3) - 1; + int z = (a_Noise.IntNoise3DInt(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) % 3) - 1; + + // The branches would end up in the trunk. + if ((x >= a_BlockX) && (x <= a_BlockX + 1) && (z >= a_BlockZ) && (z <= a_BlockZ + 1)) + { + NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z); + if (Val1 < 0) + { + x = a_BlockX + ((Val1 < -0.5) ? -1 : 3); + } + else + { + z = a_BlockZ + ((Val1 < 0.5) ? -1 : 3); + } + } + + int y = Height - (a_Noise.IntNoise3DInt(a_BlockX + x, a_BlockY * i, a_BlockZ - z) % (Height - (Height / 4))); + + for (int Y = y; Y < Height; Y++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX + x, a_BlockY + Y, a_BlockZ + z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); + } + } + + int hei = a_BlockY + Height - 2; + + // The lower two leaves layers are BigO4 with log in the middle and possibly corners: + for (int i = 0; i < 2; i++) + { + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + hei++; + } // for i < 2 + + // The top leaves layer is a BigO3 with leaves in the middle and possibly corners: + PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD)); } @@ -812,65 +865,3 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & - -void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) -{ - // Calculate a height - int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 4; - - // Creat the trunk - for (int i = 0; i < Height; i++) - { - a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); - a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); - a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); - a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); - } - - // Create branches - for (int i = 0; i < 3; i++) - { - int x = (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) % 3) - 1; - int z = (a_Noise.IntNoise3DInt(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) % 3) - 1; - - // The branches would end up in the trunk. - if ((x >= a_BlockX) && (x <= a_BlockX + 1) && (z >= a_BlockZ) && (z <= a_BlockZ + 1)) - { - NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z); - if (Val1 < 0) - { - x = a_BlockX + ((Val1 < -0.5) ? -1 : 3); - } - else - { - z = a_BlockZ + ((Val1 < 0.5) ? -1 : 3); - } - } - - int y = Height - (a_Noise.IntNoise3DInt(a_BlockX + x, a_BlockY * i, a_BlockZ - z) % (Height - (Height / 4))); - - for (int Y = y; Y < Height; Y++) - { - a_LogBlocks.push_back(sSetBlock(a_BlockX + x, a_BlockY + Y, a_BlockZ + z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); - } - } - - int hei = a_BlockY + Height - 2; - - // The lower two leaves layers are BigO4 with log in the middle and possibly corners: - for (int i = 0; i < 2; i++) - { - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); - PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); - hei++; - } // for i < 2 - - // The top leaves layer is a BigO3 with leaves in the middle and possibly corners: - PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); - PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD); - a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD)); -} - - - - diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index 2c54fce82..1f6ac4dff 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -96,8 +96,6 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & /// Generates an image of a small jungle tree (1x1 trunk) void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); -/// Generates an image of a roofed forest tree -void GetRoofedForestTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks); -- cgit v1.2.3 From 89b1bbdc5fca5a51df1a5dd18ce91f27cb667c04 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 21:59:35 +0200 Subject: Added beacon. --- src/BlockEntities/BeaconEntity.cpp | 309 +++++++++++++++++++++++++++++++--- src/BlockEntities/BeaconEntity.h | 58 +++++-- src/BlockEntities/FlowerPotEntity.cpp | 2 +- src/Blocks/BlockHandler.cpp | 1 + src/Blocks/BlockPiston.h | 1 + src/ChunkMap.cpp | 1 + src/ClientHandle.cpp | 54 ++++++ src/ClientHandle.h | 5 +- src/Protocol/Protocol17x.cpp | 15 ++ src/UI/SlotArea.cpp | 195 +++++++++++++++++++++ src/UI/SlotArea.h | 29 ++++ src/UI/Window.cpp | 31 ++++ src/UI/Window.h | 21 +++ 13 files changed, 689 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 4b9662797..af6c124c0 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -3,33 +3,31 @@ #include "BeaconEntity.h" #include "../BlockArea.h" +#include "../Entities/Player.h" -cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : - super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, a_World) +cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) + : super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World) + , m_IsActive(false) + , m_BeaconLevel(0) + , m_PrimaryPotion(cEntityEffect::effNoEffect) + , m_SecondaryPotion(cEntityEffect::effNoEffect) { + UpdateBeacon(); } -int cBeaconEntity::GetPyramidLevel(void) +char cBeaconEntity::CalculatePyramidLevel(void) { cBlockArea Area; - int MinY = GetPosY() - 4; - if (MinY < 0) - { - MinY = 0; - } - int MaxY = GetPosY() - 1; - if (MaxY < 0) - { - MaxY = 0; - } + int MinY = std::max(GetPosY() - 4, 0); + int MaxY = std::max(GetPosY() - 1, 0); Area.Read( m_World, @@ -42,7 +40,7 @@ int cBeaconEntity::GetPyramidLevel(void) int Layer = 1; int MiddleXZ = 4; - for (int Y = Area.GetSizeY() - 1; Y > 0; Y--) + for (int Y = (Area.GetSizeY() - 1); Y >= 0; Y--) { for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++) { @@ -50,14 +48,122 @@ int cBeaconEntity::GetPyramidLevel(void) { if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z))) { - return Layer - 1; + return (Layer - 1); } } } Layer++; } - return Layer - 1; + return (Layer - 1); +} + + + + + +bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel) +{ + if (a_Potion == cEntityEffect::effNoEffect) + { + return true; + } + + switch (a_BeaconLevel) + { + case 4: + { + // Beacon level 4 + if (a_Potion == cEntityEffect::effRegeneration) + { + return true; + } + } + case 3: + { + // Beacon level 3 + if (a_Potion == cEntityEffect::effStrength) + { + return true; + } + } + case 2: + { + // Beacon level 2 + switch (a_Potion) + { + case cEntityEffect::effResistance: + case cEntityEffect::effJumpBoost: + { + return true; + } + } + } + case 1: + { + // Beacon level 1 + switch (a_Potion) + { + case cEntityEffect::effSpeed: + case cEntityEffect::effHaste: + { + return true; + } + } + } + } + return false; +} + + + + + +bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion) +{ + LOG("SelectPrimaryPotion!"); + if (!IsValidPotion(a_Potion, m_BeaconLevel)) + { + LOG("FALLSE!"); + return false; + } + + m_PrimaryPotion = a_Potion; + return true; +} + + + + + +bool cBeaconEntity::SelectSecondaryPotion(cEntityEffect::eType a_Potion) +{ + if (!IsValidPotion(a_Potion, m_BeaconLevel)) + { + return false; + } + + m_SecondaryPotion = a_Potion; + return true; +} + + + + + +bool cBeaconEntity::IsBeaconBlocked(void) +{ + bool IsBlocked = false; + for (int Y = m_PosY; Y < cChunkDef::Height; ++Y) + { + BLOCKTYPE Block = m_World->GetBlock(m_PosX, Y, m_PosZ); + if (!cBlockInfo::IsTransparent(Block)) + { + IsBlocked = true; + break; + } + } + return IsBlocked; } @@ -83,8 +189,102 @@ bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType) +void cBeaconEntity::UpdateBeacon(void) +{ + if (IsBeaconBlocked()) + { + m_IsActive = false; + m_BeaconLevel = 0; + } + else + { + m_BeaconLevel = CalculatePyramidLevel(); + m_IsActive = (m_BeaconLevel > 0); + } + + // TODO: Add achievement +} + + + + + +void cBeaconEntity::GiveEffects(void) +{ + if (!m_IsActive || (m_BeaconLevel < 0)) + { + return; + } + + int Radius = m_BeaconLevel * 10 + 10; + short EffectLevel = 0; + if ((m_BeaconLevel >= 4) && (m_PrimaryPotion == m_SecondaryPotion)) + { + EffectLevel = 1; + } + + cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect; + if ((m_BeaconLevel >= 4) && (m_PrimaryPotion != m_SecondaryPotion) && (m_SecondaryPotion > 0)) + { + SecondaryPotion = m_SecondaryPotion; + } + + class cPlayerCallback : public cPlayerListCallback + { + int m_Radius; + int m_PosX, m_PosY, m_PosZ; + cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion; + short m_EffectLevel; + + virtual bool Item(cPlayer * a_Player) + { + Vector3d PlayerPosition = Vector3d(a_Player->GetPosition()); + if (PlayerPosition.y > (double)m_PosY) + { + PlayerPosition.y = (double)m_PosY; + } + + // TODO: Vanilla minecraft uses an AABB check instead of a radius one + Vector3d BeaconPosition = Vector3d(m_PosX, m_PosY, m_PosZ); + if ((PlayerPosition - BeaconPosition).Length() <= m_Radius) + { + a_Player->AddEntityEffect(m_PrimaryPotion, 180, m_EffectLevel); + + if (m_SecondaryPotion != cEntityEffect::effNoEffect) + { + a_Player->AddEntityEffect(m_SecondaryPotion, 180, 0); + } + } + return false; + } + + public: + cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryPotion, cEntityEffect::eType a_SecondaryPotion, short a_EffectLevel) + : m_Radius(a_Radius) + , m_PosX(a_PosX) + , m_PosY(a_PosY) + , m_PosZ(a_PosZ) + , m_PrimaryPotion(a_PrimaryPotion) + , m_SecondaryPotion(a_SecondaryPotion) + , m_EffectLevel(a_EffectLevel) + {}; + + } PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryPotion, SecondaryPotion, EffectLevel); + GetWorld()->ForEachPlayer(PlayerCallback); +} + + + + + bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk) { + // Update the beacon every 4 seconds + if ((GetWorld()->GetWorldAge() % 80) == 0) + { + UpdateBeacon(); + GiveEffects(); + } return false; } @@ -92,23 +292,94 @@ bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk) -void cBeaconEntity::SaveToJson(Json::Value& a_Value) +void cBeaconEntity::UsedBy(cPlayer * a_Player) { + cWindow * Window = GetWindow(); + if (Window == NULL) + { + OpenWindow(new cBeaconWindow(m_PosX, m_PosY, m_PosZ, this)); + Window = GetWindow(); + } + + if (Window != NULL) + { + // if (a_Player->GetWindow() != Window) + // -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ... + { + a_Player->OpenWindow(Window); + } + } } -void cBeaconEntity::SendTo(cClientHandle & a_Client) + +bool cBeaconEntity::LoadFromJson(const Json::Value & a_Value) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + Json::Value AllSlots = a_Value.get("Slots", 0); + int SlotIdx = 0; + for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) + { + cItem Item; + Item.FromJson(*itr); + SetSlot(SlotIdx, Item); + SlotIdx++; + } + + m_BeaconLevel = (char)a_Value.get("Level", 0).asInt(); + int PrimaryPotion = a_Value.get("PrimaryPotion", 0).asInt(); + int SecondaryPotion = a_Value.get("SecondaryPotion", 0).asInt(); + + if ((PrimaryPotion >= 0) && (PrimaryPotion <= (int)cEntityEffect::effSaturation)) + { + m_PrimaryPotion = (cEntityEffect::eType)PrimaryPotion; + } + + if ((SecondaryPotion >= 0) && (SecondaryPotion <= (int)cEntityEffect::effSaturation)) + { + m_SecondaryPotion = (cEntityEffect::eType)SecondaryPotion; + } + + return true; +} + + + + + +void cBeaconEntity::SaveToJson(Json::Value& a_Value) { + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + Json::Value AllSlots; + int NumSlots = m_Contents.GetNumSlots(); + for (int i = 0; i < NumSlots; i++) + { + Json::Value Slot; + m_Contents.GetSlot(i).GetJson(Slot); + AllSlots.append(Slot); + } + a_Value["Slots"] = AllSlots; + + a_Value["Level"] = m_BeaconLevel; + a_Value["PrimaryPotion"] = (int)m_PrimaryPotion; + a_Value["SecondaryPotion"] = (int)m_SecondaryPotion; } -void cBeaconEntity::UsedBy(cPlayer * a_Player) +void cBeaconEntity::SendTo(cClientHandle & a_Client) { + a_Client.SendUpdateBlockEntity(*this); } diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index ee1eda391..52111e82a 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -1,7 +1,7 @@ #pragma once -#include "BlockEntity.h" +#include "BlockEntityWithItems.h" @@ -17,26 +17,60 @@ namespace Json class cBeaconEntity : - public cBlockEntity + public cBlockEntityWithItems { - typedef cBlockEntity super; + typedef cBlockEntityWithItems super; public: - - /** The initial constructor */ cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - - /** Returns the amount of layers the pyramid below the beacon has. */ - int GetPyramidLevel(void); + + /** Is the beacon active? */ + bool IsActive(void) const { return m_IsActive; } + + /** Returns the beacon level. (0 - 4) */ + char GetBeaconLevel(void) const { return m_BeaconLevel; } + + char GetPrimaryPotion(void) const { return m_PrimaryPotion; } + char GetSecondaryPotion(void) const { return m_SecondaryPotion; } + + /** Select the primary potion. Returns false when the potion is invalid.*/ + bool SelectPrimaryPotion(cEntityEffect::eType a_Potion); + + /** Select the secondary potion. Returns false when the potion is invalid. */ + bool SelectSecondaryPotion(cEntityEffect::eType a_Potion); + + /** Calculate the amount of layers the pyramid below the beacon has. */ + char CalculatePyramidLevel(void); + + /** Is the beacon blocked by non-transparent blocks that are higher than the beacon? */ + bool IsBeaconBlocked(void); /** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */ static bool IsMineralBlock(BLOCKTYPE a_BlockType); + + /** Returns true if the potion can be used. */ + static bool IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel); + + /** Update the beacon. */ + void UpdateBeacon(void); + + /** Give the near-players the effects. */ + void GiveEffects(void); + + bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value& a_Value) override; - virtual void SendTo(cClientHandle & a_Client) override; - virtual void UsedBy(cPlayer * a_Player) override; - virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */) override; + virtual void SaveToJson(Json::Value& a_Value) override; + virtual void SendTo(cClientHandle & a_Client) override; + virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void UsedBy(cPlayer * a_Player) override; + +protected: + bool m_IsActive; + char m_BeaconLevel; + + cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion; + } ; diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index 87bf8b921..e001634b8 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -1,7 +1,7 @@ // FlowerPotEntity.cpp -// Implements the cFlowerPotEntity class representing a single sign in the world +// Implements the cFlowerPotEntity class representing a single flower pot in the world #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "json/json.h" diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index ddb0186c9..52f7dd608 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -181,6 +181,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); + case E_BLOCK_BEACON: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index bbb8af75b..0bec603e3 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -94,6 +94,7 @@ private: switch (a_BlockType) { case E_BLOCK_ANVIL: + case E_BLOCK_BEACON: case E_BLOCK_BEDROCK: case E_BLOCK_BREWING_STAND: case E_BLOCK_CHEST: diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 05d219918..38e0cd82d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1839,6 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } case E_BLOCK_OBSIDIAN: + case E_BLOCK_BEACON: case E_BLOCK_BEDROCK: case E_BLOCK_WATER: case E_BLOCK_LAVA: diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 30ec737be..849de2ce1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -31,6 +31,7 @@ #include "Items/ItemSword.h" #include "polarssl/md5.h" +#include "BlockEntities/BeaconEntity.h" @@ -659,6 +660,10 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString // Client <-> Server branding exchange SendPluginMessage("MC|Brand", "MCServer"); } + else if (a_Channel == "MC|Beacon") + { + HandleBeaconSelection(a_Message.c_str(), a_Message.size()); + } else if (a_Channel == "MC|ItemName") { HandleAnvilItemName(a_Message.c_str(), a_Message.size()); @@ -746,6 +751,55 @@ void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList +void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) +{ + if (a_Length < 14) + { + SendChat("Failure setting beacon selection; bad request", mtFailure); + LOGD("Malformed MC|Beacon packet."); + return; + } + + cWindow * Window = m_Player->GetWindow(); + if ((Window == NULL) || (Window->GetWindowType() != cWindow::wtBeacon)) + { + return; + } + cBeaconWindow * BeaconWindow = (cBeaconWindow *) Window; + + if (Window->GetSlot(*m_Player, 0)->IsEmpty()) + { + return; + } + + cByteBuffer Buffer(a_Length); + Buffer.Write(a_Data, a_Length); + + int PrimaryPotionID, SecondaryPotionID; + Buffer.ReadBEInt(PrimaryPotionID); + Buffer.ReadBEInt(SecondaryPotionID); + + cEntityEffect::eType PrimaryPotion = cEntityEffect::effNoEffect; + if ((PrimaryPotionID >= 0) && (PrimaryPotionID <= (int)cEntityEffect::effSaturation)) + { + PrimaryPotion = (cEntityEffect::eType)PrimaryPotionID; + } + + cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect; + if ((SecondaryPotionID >= 0) && (SecondaryPotionID <= (int)cEntityEffect::effSaturation)) + { + SecondaryPotion = (cEntityEffect::eType)SecondaryPotionID; + } + + Window->SetSlot(*m_Player, 0, cItem()); + BeaconWindow->GetBeaconEntity()->SelectPrimaryPotion(PrimaryPotion); + BeaconWindow->GetBeaconEntity()->SelectSecondaryPotion(SecondaryPotion); +} + + + + + void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Length) { if (a_Length < 14) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 48eba4de1..f3f1da417 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -399,7 +399,10 @@ private: /** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */ void UnregisterPluginChannels(const AStringVector & a_ChannelList); - + + /** Handles the "MC|Beacon" plugin message */ + void HandleBeaconSelection(const char * a_Data, size_t a_Length); + /** Handles the "MC|AdvCdm" plugin message */ void HandleCommandBlockMessage(const char * a_Data, size_t a_Length); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 45d39e0e9..8a68edd1f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -37,6 +37,7 @@ Implements the 1.7.x protocol classes: #include "../Mobs/IncludeAllMonsters.h" #include "../UI/Window.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" @@ -1328,6 +1329,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text + case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; @@ -2581,6 +2583,19 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt switch (a_BlockEntity.GetBlockType()) { + case E_BLOCK_BEACON: + { + cBeaconEntity & BeaconEntity = (cBeaconEntity &)a_BlockEntity; + + Writer.AddInt("x", BeaconEntity.GetPosX()); + Writer.AddInt("y", BeaconEntity.GetPosY()); + Writer.AddInt("z", BeaconEntity.GetPosZ()); + Writer.AddInt("Primary", BeaconEntity.GetPrimaryPotion()); + Writer.AddInt("Secondary", BeaconEntity.GetSecondaryPotion()); + Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); + Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + break; + } case E_BLOCK_COMMAND_BLOCK: { cCommandBlockEntity & CommandBlockEntity = (cCommandBlockEntity &)a_BlockEntity; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index b5f84c24c..4199bbf56 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "SlotArea.h" #include "../Entities/Player.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/EnderChestEntity.h" @@ -1190,6 +1191,200 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player) +//////////////////////////////////////////////////////////////////////////////// +// cSlotAreaBeacon: + +cSlotAreaBeacon::cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow) : + cSlotArea(1, a_ParentWindow), + m_Beacon(a_Beacon) +{ + m_Beacon->GetContents().AddListener(*this); +} + + + + + +cSlotAreaBeacon::~cSlotAreaBeacon() +{ + m_Beacon->GetContents().RemoveListener(*this); +} + + + + +bool cSlotAreaBeacon::IsPlaceableItem(short a_ItemType) +{ + switch (a_ItemType) + { + case E_ITEM_EMERALD: + case E_ITEM_DIAMOND: + case E_ITEM_GOLD: + case E_ITEM_IRON: + { + return true; + } + } + return false; +} + + + + + +void cSlotAreaBeacon::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) +{ + ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots())); + + bool bAsync = false; + if (GetSlot(a_SlotNum, a_Player) == NULL) + { + LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); + return; + } + + switch (a_ClickAction) + { + case caShiftLeftClick: + case caShiftRightClick: + { + ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); + return; + } + case caMiddleClick: + { + MiddleClicked(a_Player, a_SlotNum); + return; + } + case caDropKey: + case caCtrlDropKey: + { + DropClicked(a_Player, a_SlotNum, false); + return; + } + case caNumber1: + case caNumber2: + case caNumber3: + case caNumber4: + case caNumber5: + case caNumber6: + case caNumber7: + case caNumber8: + case caNumber9: + { + NumberClicked(a_Player, a_SlotNum, a_ClickAction); + return; + } + default: + { + break; + } + } + + cItem Slot(*GetSlot(a_SlotNum, a_Player)); + if (!Slot.IsSameType(a_ClickedItem)) + { + LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots); + LOGWARNING("My item: %s", ItemToFullString(Slot).c_str()); + LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); + bAsync = true; + } + cItem & DraggingItem = a_Player.GetDraggingItem(); + + if (DraggingItem.IsEmpty()) + { + DraggingItem = Slot; + Slot.Empty(); + } + else if (Slot.IsEmpty()) + { + if (!IsPlaceableItem(DraggingItem.m_ItemType)) + { + return; + } + + Slot = DraggingItem.CopyOne(); + DraggingItem.m_ItemCount -= 1; + if (DraggingItem.m_ItemCount <= 0) + { + DraggingItem.Empty(); + } + } + else if (DraggingItem.m_ItemCount == 1) + { + if (!IsPlaceableItem(DraggingItem.m_ItemCount)) + { + return; + } + + // Switch contents + cItem tmp(DraggingItem); + DraggingItem = Slot; + Slot = tmp; + } + + SetSlot(a_SlotNum, a_Player, Slot); + if (bAsync) + { + m_ParentWindow.BroadcastWholeWindow(); + } +} + + + + + +void cSlotAreaBeacon::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) +{ + const cItem * Slot = GetSlot(0, a_Player); + if (!Slot->IsEmpty() || !IsPlaceableItem(a_ItemStack.m_ItemType) || (a_ItemStack.m_ItemCount != 1)) + { + return; + } + + if (a_ShouldApply) + { + SetSlot(0, a_Player, a_ItemStack.CopyOne()); + } + a_ItemStack.Empty(); +} + + + + + +const cItem * cSlotAreaBeacon::GetSlot(int a_SlotNum, cPlayer & a_Player) const +{ + UNUSED(a_Player); + return &(m_Beacon->GetSlot(a_SlotNum)); +} + + + + + +void cSlotAreaBeacon::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) +{ + UNUSED(a_Player); + m_Beacon->SetSlot(a_SlotNum, a_Item); +} + + + + + +void cSlotAreaBeacon::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) +{ + UNUSED(a_SlotNum); + // Something has changed in the window, broadcast the entire window to all clients + ASSERT(a_ItemGrid == &(m_Beacon->GetContents())); + + m_ParentWindow.BroadcastWholeWindow(); +} + + + + //////////////////////////////////////////////////////////////////////////////// // cSlotAreaEnchanting: diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index fa842bb81..9a96f2f3c 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -15,6 +15,7 @@ class cWindow; class cPlayer; +class cBeaconEntity; class cChestEntity; class cDropSpenserEntity; class cEnderChestEntity; @@ -314,6 +315,34 @@ protected: +class cSlotAreaBeacon : + public cSlotArea, + public cItemGrid::cListener +{ + typedef cSlotArea super; + +public: + cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow); + virtual ~cSlotAreaBeacon(); + + bool IsPlaceableItem(short a_ItemType); + + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; + virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override; + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; + virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; + +protected: + cBeaconEntity * m_Beacon; + + // cItemGrid::cListener overrides: + virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; +} ; + + + + + class cSlotAreaEnchanting : public cSlotAreaTemporary { diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 4731f282b..aa129bfe8 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -9,6 +9,7 @@ #include "../Entities/Pickup.h" #include "../Inventory.h" #include "../Items/ItemHandler.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/EnderChestEntity.h" @@ -840,6 +841,36 @@ void cAnvilWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ) +//////////////////////////////////////////////////////////////////////////////// +// cBeaconWindow: + +cBeaconWindow::cBeaconWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconEntity * a_Beacon) : + cWindow(wtBeacon, "Beacon"), + m_Beacon(a_Beacon) +{ + m_ShouldDistributeToHotbarFirst = true; + m_SlotAreas.push_back(new cSlotAreaBeacon(m_Beacon, *this)); + m_SlotAreas.push_back(new cSlotAreaInventory(*this)); + m_SlotAreas.push_back(new cSlotAreaHotBar(*this)); +} + + + + + +void cBeaconWindow::OpenedByPlayer(cPlayer & a_Player) +{ + super::OpenedByPlayer(a_Player); + + a_Player.GetClientHandle()->SendWindowProperty(*this, 0, m_Beacon->GetBeaconLevel()); + a_Player.GetClientHandle()->SendWindowProperty(*this, 1, m_Beacon->GetPrimaryPotion()); + a_Player.GetClientHandle()->SendWindowProperty(*this, 2, m_Beacon->GetSecondaryPotion()); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cEnchantingWindow: diff --git a/src/UI/Window.h b/src/UI/Window.h index 97db0ca88..9fb0e3b38 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -23,6 +23,7 @@ class cDropSpenserEntity; class cEnderChestEntity; class cFurnaceEntity; class cHopperEntity; +class cBeaconEntity; class cSlotArea; class cSlotAreaAnvil; class cWorld; @@ -258,6 +259,26 @@ protected: +class cBeaconWindow : + public cWindow +{ + typedef cWindow super; +public: + cBeaconWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconEntity * a_Beacon); + + cBeaconEntity * GetBeaconEntity(void) const { return m_Beacon; } + + // cWindow Overrides: + virtual void OpenedByPlayer(cPlayer & a_Player) override; + +protected: + cBeaconEntity * m_Beacon; +} ; + + + + + class cEnchantingWindow : public cWindow { -- cgit v1.2.3 From 81e095adda62e4067ab4c07b0e4c7ce0f3dbce39 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 22:19:51 +0200 Subject: Exported the beacon. --- src/Bindings/AllToLua.pkg | 1 + src/Bindings/CMakeLists.txt | 1 + src/Bindings/ManualBindings.cpp | 2 ++ src/BlockEntities/BeaconEntity.cpp | 2 -- src/BlockEntities/BeaconEntity.h | 42 ++++++++++++++++++++++++-------------- src/Chunk.cpp | 33 ++++++++++++++++++++++++++++++ src/Chunk.h | 5 +++++ src/ChunkMap.cpp | 18 ++++++++++++++++ src/ChunkMap.h | 5 +++++ src/World.cpp | 10 +++++++++ src/World.h | 5 +++++ 11 files changed, 107 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 1e5dfd2fe..621358662 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -47,6 +47,7 @@ $cfile "../Inventory.h" $cfile "../Enchantments.h" $cfile "../Item.h" $cfile "../ItemGrid.h" +$cfile "../BlockEntities/BeaconEntity.h" $cfile "../BlockEntities/BlockEntity.h" $cfile "../BlockEntities/BlockEntityWithItems.h" $cfile "../BlockEntities/ChestEntity.h" diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 48e7ce79c..a2b381a26 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -53,6 +53,7 @@ set(BINDING_DEPENDENCIES ../Bindings/WebPlugin.h ../BiomeDef.h ../BlockArea.h + ../BlockEntities/BeaconEntity.h ../BlockEntities/BlockEntity.h ../BlockEntities/BlockEntityWithItems.h ../BlockEntities/ChestEntity.h diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index df9687fc0..460d879d5 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -16,6 +16,7 @@ #include "../WebAdmin.h" #include "../ClientHandle.h" #include "../BlockArea.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" @@ -2996,6 +2997,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cWorld"); tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay); tolua_function(tolua_S, "DoWithBlockEntityAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithBeaconAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithChestAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDispenserAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDropSpenserAt", tolua_DoWithXYZ); diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index af6c124c0..38b710181 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -121,10 +121,8 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion) { - LOG("SelectPrimaryPotion!"); if (!IsValidPotion(a_Potion, m_BeaconLevel)) { - LOG("FALLSE!"); return false; } diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 52111e82a..4710e91e0 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -1,3 +1,10 @@ +// BeaconEntity.h + +// Declares the cBeaconEntity class representing a single beacon in the world + + + + #pragma once @@ -16,14 +23,26 @@ namespace Json +// tolua_begin class cBeaconEntity : public cBlockEntityWithItems { typedef cBlockEntityWithItems super; public: + // tolua_end + cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); + bool LoadFromJson(const Json::Value & a_Value); + // cBlockEntity overrides: + virtual void SaveToJson(Json::Value& a_Value) override; + virtual void SendTo(cClientHandle & a_Client) override; + virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void UsedBy(cPlayer * a_Player) override; + + // tolua_begin + /** Is the beacon active? */ bool IsActive(void) const { return m_IsActive; } @@ -45,33 +64,26 @@ public: /** Is the beacon blocked by non-transparent blocks that are higher than the beacon? */ bool IsBeaconBlocked(void); - /** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */ - static bool IsMineralBlock(BLOCKTYPE a_BlockType); - - /** Returns true if the potion can be used. */ - static bool IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel); - /** Update the beacon. */ void UpdateBeacon(void); /** Give the near-players the effects. */ void GiveEffects(void); - bool LoadFromJson(const Json::Value & a_Value); - - // cBlockEntity overrides: - virtual void SaveToJson(Json::Value& a_Value) override; - virtual void SendTo(cClientHandle & a_Client) override; - virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; - virtual void UsedBy(cPlayer * a_Player) override; + /** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */ + static bool IsMineralBlock(BLOCKTYPE a_BlockType); + + /** Returns true if the potion can be used. */ + static bool IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel); + + // tolua_end protected: bool m_IsActive; char m_BeaconLevel; cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion; - -} ; +} ; // tolua_export diff --git a/src/Chunk.cpp b/src/Chunk.cpp index b83036b6d..cd7dc698c 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -11,6 +11,7 @@ #include "Server.h" #include "zlib/zlib.h" #include "Defines.h" +#include "BlockEntities/BeaconEntity.h" #include "BlockEntities/ChestEntity.h" #include "BlockEntities/DispenserEntity.h" #include "BlockEntities/DropperEntity.h" @@ -2126,6 +2127,38 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc +bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) +{ + // The blockentity list is locked by the parent chunkmap's CS + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) + { + ++itr2; + if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ)) + { + continue; + } + if ((*itr)->GetBlockType() != E_BLOCK_BEACON) + { + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; + } + + // The correct block entity is here + if (a_Callback.Item((cBeaconEntity *)*itr)) + { + return false; + } + return true; + } // for itr - m_BlockEntitites[] + + // Not found: + return false; +} + + + + + bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback) { // The blockentity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index 7eee3999c..5cde3f08f 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -28,6 +28,7 @@ class cServer; class MTRand; class cPlayer; class cChunkMap; +class cBeaconEntity; class cChestEntity; class cDispenserEntity; class cFurnaceEntity; @@ -45,6 +46,7 @@ class cMobSpawner; typedef std::list cClientHandleList; typedef cItemCallback cEntityCallback; +typedef cItemCallback cBeaconCallback; typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; @@ -236,6 +238,9 @@ public: /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible + /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ + bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible + /** 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); // Lua-acessible diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 38e0cd82d..dd8be0631 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2116,6 +2116,24 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB +bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) +{ + int ChunkX, ChunkZ; + int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + return false; + } + return Chunk->DoWithBeaconAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback) { int ChunkX, ChunkZ; diff --git a/src/ChunkMap.h b/src/ChunkMap.h index e33d9f894..1e9a0f982 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -19,6 +19,7 @@ class MTRand; class cChunkStay; class cChunk; class cPlayer; +class cBeaconEntity; class cChestEntity; class cDispenserEntity; class cDropperEntity; @@ -40,6 +41,7 @@ typedef std::list cClientHandleList; typedef cChunk * cChunkPtr; typedef cItemCallback cEntityCallback; typedef cItemCallback cBlockEntityCallback; +typedef cItemCallback cBeaconCallback; typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cDropperCallback; @@ -234,6 +236,9 @@ public: /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible + /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ + bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible + /** 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); // Lua-acessible diff --git a/src/World.cpp b/src/World.cpp index 348498693..b3c4b1de0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -25,6 +25,7 @@ #include "Entities/TNTEntity.h" #include "BlockEntities/CommandBlockEntity.h" +#include "BlockEntities/BeaconEntity.h" // Simulators: #include "Simulator/SimulatorManager.h" @@ -1232,6 +1233,15 @@ bool cWorld::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc +bool cWorld::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback& a_Callback) +{ + return m_ChunkMap->DoWithBeaconAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback) { return m_ChunkMap->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); diff --git a/src/World.h b/src/World.h index 4d0ccf2dd..90b798e8e 100644 --- a/src/World.h +++ b/src/World.h @@ -41,6 +41,7 @@ class cEntity; class cBlockEntity; class cWorldGenerator; // The generator that actually generates the chunks for a single world class cChunkGenerator; // The thread responsible for generating chunks +class cBeaconEntity; class cChestEntity; class cDispenserEntity; class cFlowerPotEntity; @@ -59,6 +60,7 @@ typedef std::vector cSetChunkDataPtrs; typedef cItemCallback cPlayerListCallback; typedef cItemCallback cEntityCallback; +typedef cItemCallback cBeaconCallback; typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; @@ -523,6 +525,9 @@ public: /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp + /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ + bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Exported in ManualBindings.cpp + /** 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 ad4fa6eba823de90f528e199c9f7e61bdb3f55f3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 22:22:06 +0200 Subject: Changed return type from GetPrimaryPotion() and GetSecondaryPotion() --- src/BlockEntities/BeaconEntity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 4710e91e0..07b2b85dc 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -49,8 +49,8 @@ public: /** Returns the beacon level. (0 - 4) */ char GetBeaconLevel(void) const { return m_BeaconLevel; } - char GetPrimaryPotion(void) const { return m_PrimaryPotion; } - char GetSecondaryPotion(void) const { return m_SecondaryPotion; } + cEntityEffect::eType GetPrimaryPotion(void) const { return m_PrimaryPotion; } + cEntityEffect::eType GetSecondaryPotion(void) const { return m_SecondaryPotion; } /** Select the primary potion. Returns false when the potion is invalid.*/ bool SelectPrimaryPotion(cEntityEffect::eType a_Potion); -- cgit v1.2.3 From 7821326370385ddcfe2ac28034727d02abf104da Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 22:43:59 +0200 Subject: Suggestions --- src/Generating/Trees.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 4786cad5a..32594d0b4 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -412,10 +412,10 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { - // Calculate a height + // Pick a height int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 4; - // Creat the trunk + // Create the trunk for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD)); -- cgit v1.2.3 From dcd226d9040409dec41c8f1f8909262946308ab0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 22:50:34 +0200 Subject: Added beacon load/save. --- src/BlockEntities/BeaconEntity.h | 3 ++ src/WorldStorage/NBTChunkSerializer.cpp | 19 +++++++++++++ src/WorldStorage/NBTChunkSerializer.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 50 ++++++++++++++++++++++++++++++++- src/WorldStorage/WSSAnvil.h | 1 + 5 files changed, 74 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 07b2b85dc..59a4bdbd9 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -41,6 +41,9 @@ public: virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; + /** Modify the beacon level. (It is needed to load the beacon corectly) */ + void SetBeaconLevel(char a_Level) { m_BeaconLevel = a_Level; } + // tolua_begin /** Is the beacon active? */ diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 4857da1b6..63387c33d 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -10,6 +10,7 @@ #include "../StringCompression.h" #include "FastNBT.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" @@ -176,6 +177,23 @@ void cNBTChunkSerializer::AddBasicTileEntity(cBlockEntity * a_Entity, const char +void cNBTChunkSerializer::AddBeaconEntity(cBeaconEntity * a_Entity) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Beacon"); + m_Writer.AddInt("Levels", a_Entity->GetBeaconLevel()); + m_Writer.AddInt("Primary", (int)a_Entity->GetPrimaryPotion()); + m_Writer.AddInt("Secondary", (int)a_Entity->GetSecondaryPotion()); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Entity->GetContents()); + m_Writer.EndList(); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity, BLOCKTYPE a_ChestType) { m_Writer.BeginCompound(""); @@ -825,6 +843,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) // Add tile-entity into NBT: switch (a_Entity->GetBlockType()) { + case E_BLOCK_BEACON: AddBeaconEntity ((cBeaconEntity *) a_Entity); break; case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break; case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *)a_Entity); break; case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 710a06a70..4c229a65c 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -20,6 +20,7 @@ class cFastNBTWriter; class cEntity; class cBlockEntity; class cBoat; +class cBeaconEntity; class cChestEntity; class cCommandBlockEntity; class cDispenserEntity; @@ -93,6 +94,7 @@ protected: // Block entities: void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID); + void AddBeaconEntity (cBeaconEntity * a_Entity); void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType); void AddDispenserEntity(cDispenserEntity * a_Entity); void AddDropperEntity (cDropperEntity * a_Entity); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 71ff3ef99..5a1972fd4 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -16,6 +16,7 @@ #include "../StringCompression.h" #include "../SetChunkData.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" @@ -582,7 +583,11 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { continue; } - if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) + if (strncmp(a_NBT.GetData(sID), "Beacon", a_NBT.GetDataLength(sID)) == 0) + { + LoadBeaconFromNBT(a_BlockEntities, a_NBT, Child); + } + else if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) { LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST); } @@ -746,6 +751,49 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a +void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + + std::auto_ptr Beacon(new cBeaconEntity(x, y, z, m_World)); + + int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels"); + if (CurrentLine >= 0) + { + Beacon->SetBeaconLevel((char)a_NBT.GetInt(CurrentLine)); + } + + CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Primary"); + if (CurrentLine >= 0) + { + Beacon->SelectPrimaryPotion((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + } + + CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Secondary"); + if (CurrentLine >= 0) + { + Beacon->SelectSecondaryPotion((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + } + + // We are better than mojang, we load/save the beacon inventory! + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items >= 0) && (a_NBT.GetType(Items) == TAG_List)) + { + LoadItemGridFromNBT(Beacon->GetContents(), a_NBT, Items); + } + + a_BlockEntities.push_back(Beacon.release()); +} + + + + + void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType) { ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 9f8714404..f8eeb8247 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -133,6 +133,7 @@ protected: */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); + void LoadBeaconFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType); void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From e6ca5a5ece61d8a4dd69b877a91f567edf2a3f63 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 30 Jul 2014 22:54:19 +0200 Subject: Added window update. --- src/BlockEntities/BeaconEntity.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 38b710181..30d927663 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -127,6 +127,12 @@ bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion) } m_PrimaryPotion = a_Potion; + + // Send window update: + if (GetWindow() != NULL) + { + GetWindow()->SetProperty(1, m_PrimaryPotion); + } return true; } @@ -142,6 +148,12 @@ bool cBeaconEntity::SelectSecondaryPotion(cEntityEffect::eType a_Potion) } m_SecondaryPotion = a_Potion; + + // Send window update: + if (GetWindow() != NULL) + { + GetWindow()->SetProperty(2, m_SecondaryPotion); + } return true; } @@ -189,6 +201,8 @@ bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType) void cBeaconEntity::UpdateBeacon(void) { + int OldBeaconLevel = m_BeaconLevel; + if (IsBeaconBlocked()) { m_IsActive = false; @@ -200,6 +214,15 @@ void cBeaconEntity::UpdateBeacon(void) m_IsActive = (m_BeaconLevel > 0); } + if (m_BeaconLevel != OldBeaconLevel) + { + // Send window update: + if (GetWindow() != NULL) + { + GetWindow()->SetProperty(0, m_BeaconLevel); + } + } + // TODO: Add achievement } -- cgit v1.2.3 From 8b519bf6e20a987c9544ef11f0df6467831cc069 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 31 Jul 2014 10:02:50 +0200 Subject: MojangAPI: Added a UseCachedOnly param to GetUUIDsFromPlayerNames(). --- src/Bindings/ManualBindings.cpp | 19 ++++++++++++++----- src/Protocol/MojangAPI.cpp | 7 +++++-- src/Protocol/MojangAPI.h | 6 ++++-- 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index b1d302560..038173c99 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2163,7 +2163,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) if ( !S.CheckParamUserTable(1, "cMojangAPI") || !S.CheckParamTable(2) || - !S.CheckParamEnd(3) + !S.CheckParamEnd(4) ) { return 0; @@ -2177,19 +2177,27 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) { lua_rawgeti(L, 2, i); AString Name; - S.GetStackValue(3, Name); + S.GetStackValue(-1, Name); if (!Name.empty()) { PlayerNames.push_back(Name); } lua_pop(L, 1); } + + // If the UseOnlyCached param was given, read it; default to false + bool ShouldUseCacheOnly = false; + if (lua_gettop(L) == 3) + { + ShouldUseCacheOnly = (lua_toboolean(L, 3) != 0); + lua_pop(L, 1); + } // Push the output table onto the stack: - lua_newtable(L); // stack index 3 + lua_newtable(L); // Get the UUIDs: - AStringVector UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames); + AStringVector UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames, ShouldUseCacheOnly); if (UUIDs.size() != PlayerNames.size()) { // A hard error has occured while processing the request, no UUIDs were returned. Return an empty table: @@ -2197,7 +2205,8 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) } // Convert to output table, PlayerName -> UUID: - for (int i = 0; i < NumNames; i++) + size_t len = UUIDs.size(); + for (size_t i = 0; i < len; i++) { if (UUIDs[i].empty()) { diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 5fbc5b476..71a5e53de 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -129,7 +129,7 @@ void cMojangAPI::Start(cIniFile & a_SettingsIni) -AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames) +AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached) { // Convert all playernames to lowercase: AStringVector PlayerNames; @@ -140,7 +140,10 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player } // for itr - a_PlayerNames[] // Request the cache to populate any names not yet contained: - CacheNamesToUUIDs(PlayerNames); + if (!a_UseOnlyCached) + { + CacheNamesToUUIDs(PlayerNames); + } // Retrieve from cache: size_t idx = 0; diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index c99f940ad..ac8995bb5 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -50,8 +50,10 @@ public: /** Converts the player names into UUIDs. a_PlayerName[idx] will be converted to UUID and returned as idx-th value The UUID will be empty on error. - Blocking operation, do not use in world-tick thread! */ - AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName); + If a_UseOnlyCached is true, only the cached values are returned. + If a_UseOnlyCached is false, the names not found in the cache are looked up online, which is a blocking + operation, do not use this in world-tick thread! */ + AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false); // tolua_begin -- cgit v1.2.3 From 556fc908aedcc36388e9d859487b140045e5e33e Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 12:13:11 +0200 Subject: Renamed functions and added beacon json saving. --- src/BlockEntities/BeaconEntity.cpp | 78 ++++++++++++++++----------------- src/BlockEntities/BeaconEntity.h | 12 ++--- src/ClientHandle.cpp | 24 +++++----- src/Protocol/Protocol17x.cpp | 4 +- src/UI/Window.cpp | 4 +- src/WorldStorage/NBTChunkSerializer.cpp | 4 +- src/WorldStorage/WSSAnvil.cpp | 4 +- src/WorldStorage/WSSCompact.cpp | 20 +++++++++ 8 files changed, 84 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 30d927663..c94783ba8 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -13,8 +13,8 @@ cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * : super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World) , m_IsActive(false) , m_BeaconLevel(0) - , m_PrimaryPotion(cEntityEffect::effNoEffect) - , m_SecondaryPotion(cEntityEffect::effNoEffect) + , m_PrimaryEffect(cEntityEffect::effNoEffect) + , m_SecondaryEffect(cEntityEffect::effNoEffect) { UpdateBeacon(); } @@ -62,9 +62,9 @@ char cBeaconEntity::CalculatePyramidLevel(void) -bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel) +bool cBeaconEntity::IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLevel) { - if (a_Potion == cEntityEffect::effNoEffect) + if (a_Effect == cEntityEffect::effNoEffect) { return true; } @@ -74,7 +74,7 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe case 4: { // Beacon level 4 - if (a_Potion == cEntityEffect::effRegeneration) + if (a_Effect == cEntityEffect::effRegeneration) { return true; } @@ -82,7 +82,7 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe case 3: { // Beacon level 3 - if (a_Potion == cEntityEffect::effStrength) + if (a_Effect == cEntityEffect::effStrength) { return true; } @@ -90,7 +90,7 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe case 2: { // Beacon level 2 - switch (a_Potion) + switch (a_Effect) { case cEntityEffect::effResistance: case cEntityEffect::effJumpBoost: @@ -102,7 +102,7 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe case 1: { // Beacon level 1 - switch (a_Potion) + switch (a_Effect) { case cEntityEffect::effSpeed: case cEntityEffect::effHaste: @@ -119,19 +119,19 @@ bool cBeaconEntity::IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLe -bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion) +bool cBeaconEntity::SelectPrimaryEffect(cEntityEffect::eType a_Effect) { - if (!IsValidPotion(a_Potion, m_BeaconLevel)) + if (!IsValidEffect(a_Effect, m_BeaconLevel)) { return false; } - m_PrimaryPotion = a_Potion; + m_PrimaryEffect = a_Effect; // Send window update: if (GetWindow() != NULL) { - GetWindow()->SetProperty(1, m_PrimaryPotion); + GetWindow()->SetProperty(1, m_PrimaryEffect); } return true; } @@ -140,19 +140,19 @@ bool cBeaconEntity::SelectPrimaryPotion(cEntityEffect::eType a_Potion) -bool cBeaconEntity::SelectSecondaryPotion(cEntityEffect::eType a_Potion) +bool cBeaconEntity::SelectSecondaryEffect(cEntityEffect::eType a_Effect) { - if (!IsValidPotion(a_Potion, m_BeaconLevel)) + if (!IsValidEffect(a_Effect, m_BeaconLevel)) { return false; } - m_SecondaryPotion = a_Potion; + m_SecondaryEffect = a_Effect; // Send window update: if (GetWindow() != NULL) { - GetWindow()->SetProperty(2, m_SecondaryPotion); + GetWindow()->SetProperty(2, m_SecondaryEffect); } return true; } @@ -163,17 +163,15 @@ bool cBeaconEntity::SelectSecondaryPotion(cEntityEffect::eType a_Potion) bool cBeaconEntity::IsBeaconBlocked(void) { - bool IsBlocked = false; for (int Y = m_PosY; Y < cChunkDef::Height; ++Y) { BLOCKTYPE Block = m_World->GetBlock(m_PosX, Y, m_PosZ); if (!cBlockInfo::IsTransparent(Block)) { - IsBlocked = true; - break; + return true; } } - return IsBlocked; + return false; } @@ -239,22 +237,22 @@ void cBeaconEntity::GiveEffects(void) int Radius = m_BeaconLevel * 10 + 10; short EffectLevel = 0; - if ((m_BeaconLevel >= 4) && (m_PrimaryPotion == m_SecondaryPotion)) + if ((m_BeaconLevel >= 4) && (m_PrimaryEffect == m_SecondaryEffect)) { EffectLevel = 1; } - cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect; - if ((m_BeaconLevel >= 4) && (m_PrimaryPotion != m_SecondaryPotion) && (m_SecondaryPotion > 0)) + cEntityEffect::eType SecondaryEffect = cEntityEffect::effNoEffect; + if ((m_BeaconLevel >= 4) && (m_PrimaryEffect != m_SecondaryEffect) && (m_SecondaryEffect > 0)) { - SecondaryPotion = m_SecondaryPotion; + SecondaryEffect = m_SecondaryEffect; } class cPlayerCallback : public cPlayerListCallback { int m_Radius; int m_PosX, m_PosY, m_PosZ; - cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion; + cEntityEffect::eType m_PrimaryEffect, m_SecondaryEffect; short m_EffectLevel; virtual bool Item(cPlayer * a_Player) @@ -269,28 +267,28 @@ void cBeaconEntity::GiveEffects(void) Vector3d BeaconPosition = Vector3d(m_PosX, m_PosY, m_PosZ); if ((PlayerPosition - BeaconPosition).Length() <= m_Radius) { - a_Player->AddEntityEffect(m_PrimaryPotion, 180, m_EffectLevel); + a_Player->AddEntityEffect(m_PrimaryEffect, 180, m_EffectLevel); - if (m_SecondaryPotion != cEntityEffect::effNoEffect) + if (m_SecondaryEffect != cEntityEffect::effNoEffect) { - a_Player->AddEntityEffect(m_SecondaryPotion, 180, 0); + a_Player->AddEntityEffect(m_SecondaryEffect, 180, 0); } } return false; } public: - cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryPotion, cEntityEffect::eType a_SecondaryPotion, short a_EffectLevel) + cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel) : m_Radius(a_Radius) , m_PosX(a_PosX) , m_PosY(a_PosY) , m_PosZ(a_PosZ) - , m_PrimaryPotion(a_PrimaryPotion) - , m_SecondaryPotion(a_SecondaryPotion) + , m_PrimaryEffect(a_PrimaryEffect) + , m_SecondaryEffect(a_SecondaryEffect) , m_EffectLevel(a_EffectLevel) {}; - } PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryPotion, SecondaryPotion, EffectLevel); + } PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryEffect, SecondaryEffect, EffectLevel); GetWorld()->ForEachPlayer(PlayerCallback); } @@ -353,17 +351,17 @@ bool cBeaconEntity::LoadFromJson(const Json::Value & a_Value) } m_BeaconLevel = (char)a_Value.get("Level", 0).asInt(); - int PrimaryPotion = a_Value.get("PrimaryPotion", 0).asInt(); - int SecondaryPotion = a_Value.get("SecondaryPotion", 0).asInt(); + int PrimaryEffect = a_Value.get("PrimaryEffect", 0).asInt(); + int SecondaryEffect = a_Value.get("SecondaryEffect", 0).asInt(); - if ((PrimaryPotion >= 0) && (PrimaryPotion <= (int)cEntityEffect::effSaturation)) + if ((PrimaryEffect >= 0) && (PrimaryEffect <= (int)cEntityEffect::effSaturation)) { - m_PrimaryPotion = (cEntityEffect::eType)PrimaryPotion; + m_PrimaryEffect = (cEntityEffect::eType)PrimaryEffect; } - if ((SecondaryPotion >= 0) && (SecondaryPotion <= (int)cEntityEffect::effSaturation)) + if ((SecondaryEffect >= 0) && (SecondaryEffect <= (int)cEntityEffect::effSaturation)) { - m_SecondaryPotion = (cEntityEffect::eType)SecondaryPotion; + m_SecondaryEffect = (cEntityEffect::eType)SecondaryEffect; } return true; @@ -390,8 +388,8 @@ void cBeaconEntity::SaveToJson(Json::Value& a_Value) a_Value["Slots"] = AllSlots; a_Value["Level"] = m_BeaconLevel; - a_Value["PrimaryPotion"] = (int)m_PrimaryPotion; - a_Value["SecondaryPotion"] = (int)m_SecondaryPotion; + a_Value["PrimaryEffect"] = (int)m_PrimaryEffect; + a_Value["SecondaryEffect"] = (int)m_SecondaryEffect; } diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 59a4bdbd9..5cf8da24e 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -52,14 +52,14 @@ public: /** Returns the beacon level. (0 - 4) */ char GetBeaconLevel(void) const { return m_BeaconLevel; } - cEntityEffect::eType GetPrimaryPotion(void) const { return m_PrimaryPotion; } - cEntityEffect::eType GetSecondaryPotion(void) const { return m_SecondaryPotion; } + cEntityEffect::eType GetPrimaryEffect(void) const { return m_PrimaryEffect; } + cEntityEffect::eType GetSecondaryEffect(void) const { return m_SecondaryEffect; } /** Select the primary potion. Returns false when the potion is invalid.*/ - bool SelectPrimaryPotion(cEntityEffect::eType a_Potion); + bool SelectPrimaryEffect(cEntityEffect::eType a_Effect); /** Select the secondary potion. Returns false when the potion is invalid. */ - bool SelectSecondaryPotion(cEntityEffect::eType a_Potion); + bool SelectSecondaryEffect(cEntityEffect::eType a_Effect); /** Calculate the amount of layers the pyramid below the beacon has. */ char CalculatePyramidLevel(void); @@ -77,7 +77,7 @@ public: static bool IsMineralBlock(BLOCKTYPE a_BlockType); /** Returns true if the potion can be used. */ - static bool IsValidPotion(cEntityEffect::eType a_Potion, char a_BeaconLevel); + static bool IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLevel); // tolua_end @@ -85,7 +85,7 @@ protected: bool m_IsActive; char m_BeaconLevel; - cEntityEffect::eType m_PrimaryPotion, m_SecondaryPotion; + cEntityEffect::eType m_PrimaryEffect, m_SecondaryEffect; } ; // tolua_export diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 849de2ce1..e833f338a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -7,6 +7,7 @@ #include "Bindings/PluginManager.h" #include "Entities/Player.h" #include "Inventory.h" +#include "BlockEntities/BeaconEntity.h" #include "BlockEntities/ChestEntity.h" #include "BlockEntities/CommandBlockEntity.h" #include "BlockEntities/SignEntity.h" @@ -31,7 +32,6 @@ #include "Items/ItemSword.h" #include "polarssl/md5.h" -#include "BlockEntities/BeaconEntity.h" @@ -775,25 +775,25 @@ void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) cByteBuffer Buffer(a_Length); Buffer.Write(a_Data, a_Length); - int PrimaryPotionID, SecondaryPotionID; - Buffer.ReadBEInt(PrimaryPotionID); - Buffer.ReadBEInt(SecondaryPotionID); + int PrimaryEffectID, SecondaryEffectID; + Buffer.ReadBEInt(PrimaryEffectID); + Buffer.ReadBEInt(SecondaryEffectID); - cEntityEffect::eType PrimaryPotion = cEntityEffect::effNoEffect; - if ((PrimaryPotionID >= 0) && (PrimaryPotionID <= (int)cEntityEffect::effSaturation)) + cEntityEffect::eType PrimaryEffect = cEntityEffect::effNoEffect; + if ((PrimaryEffectID >= 0) && (PrimaryEffectID <= (int)cEntityEffect::effSaturation)) { - PrimaryPotion = (cEntityEffect::eType)PrimaryPotionID; + PrimaryEffect = (cEntityEffect::eType)PrimaryEffectID; } - cEntityEffect::eType SecondaryPotion = cEntityEffect::effNoEffect; - if ((SecondaryPotionID >= 0) && (SecondaryPotionID <= (int)cEntityEffect::effSaturation)) + cEntityEffect::eType SecondaryEffect = cEntityEffect::effNoEffect; + if ((SecondaryEffectID >= 0) && (SecondaryEffectID <= (int)cEntityEffect::effSaturation)) { - SecondaryPotion = (cEntityEffect::eType)SecondaryPotionID; + SecondaryEffect = (cEntityEffect::eType)SecondaryEffectID; } Window->SetSlot(*m_Player, 0, cItem()); - BeaconWindow->GetBeaconEntity()->SelectPrimaryPotion(PrimaryPotion); - BeaconWindow->GetBeaconEntity()->SelectSecondaryPotion(SecondaryPotion); + BeaconWindow->GetBeaconEntity()->SelectPrimaryEffect(PrimaryEffect); + BeaconWindow->GetBeaconEntity()->SelectSecondaryEffect(SecondaryEffect); } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 8a68edd1f..8e31e211c 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2590,8 +2590,8 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddInt("x", BeaconEntity.GetPosX()); Writer.AddInt("y", BeaconEntity.GetPosY()); Writer.AddInt("z", BeaconEntity.GetPosZ()); - Writer.AddInt("Primary", BeaconEntity.GetPrimaryPotion()); - Writer.AddInt("Secondary", BeaconEntity.GetSecondaryPotion()); + Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); + Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index aa129bfe8..8f4913030 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -863,8 +863,8 @@ void cBeaconWindow::OpenedByPlayer(cPlayer & a_Player) super::OpenedByPlayer(a_Player); a_Player.GetClientHandle()->SendWindowProperty(*this, 0, m_Beacon->GetBeaconLevel()); - a_Player.GetClientHandle()->SendWindowProperty(*this, 1, m_Beacon->GetPrimaryPotion()); - a_Player.GetClientHandle()->SendWindowProperty(*this, 2, m_Beacon->GetSecondaryPotion()); + a_Player.GetClientHandle()->SendWindowProperty(*this, 1, m_Beacon->GetPrimaryEffect()); + a_Player.GetClientHandle()->SendWindowProperty(*this, 2, m_Beacon->GetSecondaryEffect()); } diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 63387c33d..601cd8833 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -182,8 +182,8 @@ void cNBTChunkSerializer::AddBeaconEntity(cBeaconEntity * a_Entity) m_Writer.BeginCompound(""); AddBasicTileEntity(a_Entity, "Beacon"); m_Writer.AddInt("Levels", a_Entity->GetBeaconLevel()); - m_Writer.AddInt("Primary", (int)a_Entity->GetPrimaryPotion()); - m_Writer.AddInt("Secondary", (int)a_Entity->GetSecondaryPotion()); + m_Writer.AddInt("Primary", (int)a_Entity->GetPrimaryEffect()); + m_Writer.AddInt("Secondary", (int)a_Entity->GetSecondaryEffect()); m_Writer.BeginList("Items", TAG_Compound); AddItemGrid(a_Entity->GetContents()); m_Writer.EndList(); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 5a1972fd4..555ef410d 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -771,13 +771,13 @@ void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cPar CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Primary"); if (CurrentLine >= 0) { - Beacon->SelectPrimaryPotion((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + Beacon->SelectPrimaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); } CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Secondary"); if (CurrentLine >= 0) { - Beacon->SelectSecondaryPotion((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + Beacon->SelectSecondaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); } // We are better than mojang, we load/save the beacon inventory! diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index ee47047a0..58f9e3cab 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -9,6 +9,7 @@ #include "zlib/zlib.h" #include "json/json.h" #include "../StringCompression.h" +#include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" @@ -75,6 +76,7 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) const char * SaveInto = NULL; switch (a_BlockEntity->GetBlockType()) { + case E_BLOCK_BEACON: SaveInto = "Beacons"; break; case E_BLOCK_CHEST: SaveInto = "Chests"; break; case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; break; case E_BLOCK_DROPPER: SaveInto = "Droppers"; break; @@ -268,6 +270,24 @@ bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) { + // Load beacon: + Json::Value AllBeacons = a_Value.get("Beacons", Json::nullValue); + if (!AllBeacons.empty()) + { + for (Json::Value::iterator itr = AllBeacons.begin(); itr != AllBeacons.end(); ++itr) + { + std::auto_ptr BeaconEntity(new cBeaconEntity(0, 0, 0, a_World)); + if (!BeaconEntity->LoadFromJson(*itr)) + { + LOGWARNING("ERROR READING BEACON FROM JSON!"); + } + else + { + a_BlockEntities.push_back(BeaconEntity.release()); + } + } // for itr - AllBeacons[] + } + // Load chests: Json::Value AllChests = a_Value.get("Chests", Json::nullValue); if (!AllChests.empty()) -- cgit v1.2.3 From c49d4fd215170da29b5c285cc6a344ec102764c6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 12:15:18 +0200 Subject: Updated documentation. --- src/BlockEntities/BeaconEntity.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 5cf8da24e..cc8ee8ad2 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -55,10 +55,10 @@ public: cEntityEffect::eType GetPrimaryEffect(void) const { return m_PrimaryEffect; } cEntityEffect::eType GetSecondaryEffect(void) const { return m_SecondaryEffect; } - /** Select the primary potion. Returns false when the potion is invalid.*/ + /** Select the primary effect. Returns false when the effect is invalid.*/ bool SelectPrimaryEffect(cEntityEffect::eType a_Effect); - /** Select the secondary potion. Returns false when the potion is invalid. */ + /** Select the secondary effect. Returns false when the effect is invalid. */ bool SelectSecondaryEffect(cEntityEffect::eType a_Effect); /** Calculate the amount of layers the pyramid below the beacon has. */ @@ -76,7 +76,7 @@ public: /** Returns true if the block is a diamond block, a golden block, an iron block or an emerald block. */ static bool IsMineralBlock(BLOCKTYPE a_BlockType); - /** Returns true if the potion can be used. */ + /** Returns true if the effect can be used. */ static bool IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLevel); // tolua_end -- cgit v1.2.3 From 59adf113f0ba6414edf061fc4ffbf2bb2b904883 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 31 Jul 2014 17:22:48 +0200 Subject: MojangAPI: Moved the settings to a separate ini section. --- src/Protocol/MojangAPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 71a5e53de..fa99d63fd 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -120,8 +120,8 @@ cMojangAPI::~cMojangAPI() void cMojangAPI::Start(cIniFile & a_SettingsIni) { - m_NameToUUIDServer = a_SettingsIni.GetValueSet("Authentication", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); - m_NameToUUIDAddress = a_SettingsIni.GetValueSet("Authentication", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); + m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); + m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); LoadCachesFromDisk(); } -- cgit v1.2.3 From 6b1f7e7a45ebc04f39bb54edc85fbe9c9d0659e7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 18:15:39 +0200 Subject: Renamed "select..." methods to "set..." and better IsValidEffect() function. --- src/BlockEntities/BeaconEntity.cpp | 58 ++++++++------------------------------ src/BlockEntities/BeaconEntity.h | 8 +++--- src/ClientHandle.cpp | 4 +-- src/WorldStorage/WSSAnvil.cpp | 4 +-- 4 files changed, 19 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index c94783ba8..55c5ccb7f 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -64,54 +64,18 @@ char cBeaconEntity::CalculatePyramidLevel(void) bool cBeaconEntity::IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLevel) { - if (a_Effect == cEntityEffect::effNoEffect) + switch (a_Effect) { - return true; + case cEntityEffect::effRegeneration: return (a_BeaconLevel >= 4); + case cEntityEffect::effStrength: return (a_BeaconLevel >= 3); + case cEntityEffect::effResistance: return (a_BeaconLevel >= 2); + case cEntityEffect::effJumpBoost: return (a_BeaconLevel >= 2); + case cEntityEffect::effSpeed: return (a_BeaconLevel >= 1); + case cEntityEffect::effHaste: return (a_BeaconLevel >= 1); + case cEntityEffect::effNoEffect: return true; } - switch (a_BeaconLevel) - { - case 4: - { - // Beacon level 4 - if (a_Effect == cEntityEffect::effRegeneration) - { - return true; - } - } - case 3: - { - // Beacon level 3 - if (a_Effect == cEntityEffect::effStrength) - { - return true; - } - } - case 2: - { - // Beacon level 2 - switch (a_Effect) - { - case cEntityEffect::effResistance: - case cEntityEffect::effJumpBoost: - { - return true; - } - } - } - case 1: - { - // Beacon level 1 - switch (a_Effect) - { - case cEntityEffect::effSpeed: - case cEntityEffect::effHaste: - { - return true; - } - } - } - } + LOGD("%s: Invalid beacon effect: %d", __FUNCTION__, (int)a_Effect); return false; } @@ -119,7 +83,7 @@ bool cBeaconEntity::IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLe -bool cBeaconEntity::SelectPrimaryEffect(cEntityEffect::eType a_Effect) +bool cBeaconEntity::SetPrimaryEffect(cEntityEffect::eType a_Effect) { if (!IsValidEffect(a_Effect, m_BeaconLevel)) { @@ -140,7 +104,7 @@ bool cBeaconEntity::SelectPrimaryEffect(cEntityEffect::eType a_Effect) -bool cBeaconEntity::SelectSecondaryEffect(cEntityEffect::eType a_Effect) +bool cBeaconEntity::SetSecondaryEffect(cEntityEffect::eType a_Effect) { if (!IsValidEffect(a_Effect, m_BeaconLevel)) { diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index cc8ee8ad2..0d7150aef 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -55,11 +55,11 @@ public: cEntityEffect::eType GetPrimaryEffect(void) const { return m_PrimaryEffect; } cEntityEffect::eType GetSecondaryEffect(void) const { return m_SecondaryEffect; } - /** Select the primary effect. Returns false when the effect is invalid.*/ - bool SelectPrimaryEffect(cEntityEffect::eType a_Effect); + /** Sets the primary effect. Returns false when the effect is invalid. */ + bool SetPrimaryEffect(cEntityEffect::eType a_Effect); - /** Select the secondary effect. Returns false when the effect is invalid. */ - bool SelectSecondaryEffect(cEntityEffect::eType a_Effect); + /** Sets the secondary effect. Returns false when the effect is invalid. */ + bool SetSecondaryEffect(cEntityEffect::eType a_Effect); /** Calculate the amount of layers the pyramid below the beacon has. */ char CalculatePyramidLevel(void); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e833f338a..3ce506e1e 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -792,8 +792,8 @@ void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) } Window->SetSlot(*m_Player, 0, cItem()); - BeaconWindow->GetBeaconEntity()->SelectPrimaryEffect(PrimaryEffect); - BeaconWindow->GetBeaconEntity()->SelectSecondaryEffect(SecondaryEffect); + BeaconWindow->GetBeaconEntity()->SetPrimaryEffect(PrimaryEffect); + BeaconWindow->GetBeaconEntity()->SetSecondaryEffect(SecondaryEffect); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 555ef410d..d3a156ee1 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -771,13 +771,13 @@ void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cPar CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Primary"); if (CurrentLine >= 0) { - Beacon->SelectPrimaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + Beacon->SetPrimaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); } CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Secondary"); if (CurrentLine >= 0) { - Beacon->SelectSecondaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); + Beacon->SetSecondaryEffect((cEntityEffect::eType)a_NBT.GetInt(CurrentLine)); } // We are better than mojang, we load/save the beacon inventory! -- cgit v1.2.3 From f47765dcbd8781d32f231d1ecdf4aac0b8c330ba Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 18:21:45 +0200 Subject: Added a default value to WaterSimulator, LavaSimulator and RedstoneSimulator. --- src/World.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 348498693..b247a79bc 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3176,7 +3176,7 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile) { - AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", ""); + AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "incremental"); if (SimulatorName.empty()) { @@ -3210,7 +3210,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c Printf(SimulatorNameKey, "%sSimulator", a_FluidName); AString SimulatorSectionName; Printf(SimulatorSectionName, "%sSimulator", a_FluidName); - AString SimulatorName = a_IniFile.GetValueSet("Physics", SimulatorNameKey, ""); + AString SimulatorName = a_IniFile.GetValueSet("Physics", SimulatorNameKey, "Vanilla"); if (SimulatorName.empty()) { LOGWARNING("[Physics] %s not present or empty in %s, using the default of \"Vanilla\".", SimulatorNameKey.c_str(), GetIniFileName().c_str()); -- cgit v1.2.3 From bffad5043619d143d595806122dc625746126ed8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 18:41:48 +0200 Subject: Fixed water from ice and removed packed ice drop. --- src/Blocks/BlockIce.h | 14 ++++++++++++-- src/Items/ItemHandler.cpp | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index c50623594..c085e9290 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -24,9 +24,19 @@ public: } - virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override { - // TODO: Ice destroyed with air below it should turn into air instead of water + if (a_Player->IsGameModeCreative() || (a_BlockY <= 0)) + { + return; + } + + BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + if (!cBlockInfo::IsSolid(BlockBelow) && !IsBlockLava(BlockBelow) && !IsBlockWater(BlockBelow)) + { + return; + } + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0); // This is called later than the real destroying of this ice block } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index d36b5d663..acfd1e648 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -578,6 +578,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_BLOCK: case E_BLOCK_SNOW: case E_BLOCK_VINES: + case E_BLOCK_PACKED_ICE: { return false; } -- cgit v1.2.3 From ffd6797fe106c805646e2acfe5320594cc59ece4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 31 Jul 2014 18:17:21 +0100 Subject: Comment suggestions --- src/Mobs/Enderman.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index f1f366d3b..a32e4e175 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -22,7 +22,7 @@ public: virtual bool Item(cPlayer * a_Player) override { - // Don't check players who are in creative gamemode. + // Don't check players who are in creative gamemode if (a_Player->IsGameModeCreative()) { return false; @@ -30,13 +30,13 @@ public: Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); - // Don't check players who are more then 64 blocks away. + // Don't check players who are more then 64 blocks away if (Direction.SqrLength() > 64) { return false; } - // Don't check if the player has a pumpkin on his head. + // Don't check if the player has a pumpkin on his head if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) { return false; @@ -46,9 +46,8 @@ public: Vector3d LookVector = a_Player->GetLookVector(); double dot = Direction.Dot(LookVector); - // 0.09 rad ~ 5 degrees. - // If the players crosshair is within 5 degrees of the endermen - // It counts as looking. + // 0.09 rad ~ 5 degrees + // If the player's crosshair is within 5 degrees of the enderman, it counts as looking if (dot > cos(0.09)) { return false; @@ -119,17 +118,17 @@ void cEnderman::CheckEventSeePlayer() int ChunkX, ChunkZ; cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); - // Check if the chunk the enderman is in is lit. + // Check if the chunk the enderman is in is lit if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) { m_World->QueueLightChunk(ChunkX, ChunkZ); return; } - // Enderman only attack if the skylight is higher than 6 + // Enderman only attack if the skylight is higher than 7 if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) <= 7) { - // TODO: Teleport the enderman to a random spot. + // TODO: Teleport the enderman to a random spot return; } -- cgit v1.2.3 From ecb86935f87ce2b9f1ae4671d8a8b722c798b8a2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 31 Jul 2014 22:52:06 +0200 Subject: Fixed UUIDs handling in cPlayer. The loading expected dashed UUIDs, MCS uses short UUIDs throughout. --- src/Entities/Player.cpp | 13 ++++++++----- src/Entities/Player.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index fcc8eb9a0..477334948 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1700,8 +1700,10 @@ bool cPlayer::LoadFromDisk(void) // Load from the offline UUID file, if allowed: AString OfflineUUID = cClientHandle::GenerateOfflineUUID(GetName()); + const char * OfflineUsage = " (unused)"; if (cRoot::Get()->GetServer()->ShouldLoadOfflinePlayerData()) { + OfflineUsage = ""; if (LoadFromFile(GetUUIDFileName(OfflineUUID))) { return true; @@ -1724,8 +1726,8 @@ bool cPlayer::LoadFromDisk(void) } // None of the files loaded successfully - LOG("Player data file not found for %s (%s, offline %s), will be reset to defaults.", - GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str() + LOG("Player data file not found for %s (%s, offline %s%s), will be reset to defaults.", + GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str(), OfflineUsage ); return false; } @@ -2212,12 +2214,13 @@ void cPlayer::Detach() AString cPlayer::GetUUIDFileName(const AString & a_UUID) { - ASSERT(a_UUID.size() == 36); + AString UUID = cMojangAPI::MakeUUIDDashed(a_UUID); + ASSERT(UUID.length() == 36); AString res("players/"); - res.append(a_UUID, 0, 2); + res.append(UUID, 0, 2); res.push_back('/'); - res.append(a_UUID, 2, AString::npos); + res.append(UUID, 2, AString::npos); res.append(".json"); return res; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 488884602..29bb4c39d 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -536,7 +536,7 @@ protected: */ bool m_bIsTeleporting; - /** The UUID of the player, as read from the ClientHandle. + /** The short UUID (no dashes) of the player, as read from the ClientHandle. If no ClientHandle is given, the UUID is initialized to empty. */ AString m_UUID; -- cgit v1.2.3 From 70fd7caf1f879b0588042d6542c27ef8f0909a43 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 31 Jul 2014 22:54:45 +0200 Subject: Removed trailing whitespace. --- src/Protocol/MojangAPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index fa99d63fd..45baa5a4f 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -245,7 +245,7 @@ AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) return a_UUID; } - case 36: + case 36: { // Remove the dashes from the string: AString res; @@ -277,7 +277,7 @@ AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) return a_UUID; } - case 32: + case 32: { // Insert dashes at the proper positions: AString res; -- cgit v1.2.3 From 84462ba8b20c28136c6a7923323f7cde28a86d70 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 23:04:00 +0200 Subject: Fixed hunger bugs, Implemented golden apple, added jump statistic, added correct food effects. --- src/ClientHandle.cpp | 4 ++- src/Entities/EntityEffect.cpp | 2 +- src/Entities/Player.cpp | 53 ++++++++++++++++++++++++++------------- src/Entities/Player.h | 5 +--- src/Items/ItemFood.h | 54 ++++++++++++++++++++++++++++++++++------ src/Items/ItemGoldenApple.h | 58 +++++++++++++++++++++++++++++++++++++++++++ src/Items/ItemHandler.cpp | 33 ++++++++++++++++-------- src/Items/ItemHandler.h | 16 ++++++------ 8 files changed, 177 insertions(+), 48 deletions(-) create mode 100644 src/Items/ItemGoldenApple.h (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 30ec737be..bd76ef227 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -634,6 +634,7 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, if (!m_Player->IsSwimming()) { + m_Player->GetStatManager().AddValue(eStatistic::statJumps, 1); m_Player->AddFoodExhaustion(m_Player->IsSprinting() ? 0.8 : 0.2); } } @@ -1067,6 +1068,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo return; } + m_Player->AddFoodExhaustion(0.025); ItemHandler->OnBlockDestroyed(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ); // The ItemHandler is also responsible for spawning the pickups cChunkInterface ChunkInterface(World->GetChunkMap()); @@ -1212,7 +1214,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e else if ((ItemHandler->IsFood() || ItemHandler->IsDrinkable(EquippedDamage))) { if ((m_Player->IsSatiated() || m_Player->IsGameModeCreative()) && - ItemHandler->IsFood()) + ItemHandler->IsFood() && (Equipped.m_ItemType != E_ITEM_GOLDEN_APPLE)) { // The player is satiated or in creative, and trying to eat return; diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index fdcbe822e..39314f256 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -309,7 +309,7 @@ void cEntityEffectHunger::OnTick(cPawn & a_Target) if (a_Target.IsPlayer()) { cPlayer & Target = (cPlayer &) a_Target; - Target.SetFoodExhaustionLevel(Target.GetFoodExhaustionLevel() + 0.025); // 0.5 per second = 0.025 per tick + Target.AddFoodExhaustion(0.025 * ((double)GetIntensity() + 1.0)); // 0.5 per second = 0.025 per tick } } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 603fc7937..c9d885b89 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -545,7 +545,7 @@ void cPlayer::SetFoodTickTimer(int a_FoodTickTimer) void cPlayer::SetFoodExhaustionLevel(double a_FoodExhaustionLevel) { - m_FoodExhaustionLevel = std::max(0.0, std::min(a_FoodExhaustionLevel, 4.0)); + m_FoodExhaustionLevel = std::max(0.0, std::min(a_FoodExhaustionLevel, 40.0)); } @@ -568,6 +568,18 @@ bool cPlayer::Feed(int a_Food, double a_Saturation) +void cPlayer::AddFoodExhaustion(double a_Exhaustion) +{ + if (!IsGameModeCreative()) + { + m_FoodExhaustionLevel = std::min(m_FoodExhaustionLevel + a_Exhaustion, 40.0); + } +} + + + + + void cPlayer::FoodPoison(int a_NumTicks) { AddEntityEffect(cEntityEffect::effHunger, a_NumTicks, 0, 1); @@ -1979,19 +1991,34 @@ void cPlayer::HandleFood(void) return; } + // Apply food exhaustion that has accumulated: + if (m_FoodExhaustionLevel > 4.0) + { + m_FoodExhaustionLevel -= 4.0; + + if (m_FoodSaturationLevel > 0.0) + { + m_FoodSaturationLevel = std::max(m_FoodSaturationLevel - 1.0, 0.0); + } + else + { + SetFoodLevel(m_FoodLevel - 1); + } + } + // Heal or damage, based on the food level, using the m_FoodTickTimer: - if ((m_FoodLevel > 17) || (m_FoodLevel <= 0)) + if ((m_FoodLevel >= 18) || (m_FoodLevel <= 0)) { m_FoodTickTimer++; if (m_FoodTickTimer >= 80) { m_FoodTickTimer = 0; - if ((m_FoodLevel > 17) && (GetHealth() < GetMaxHealth())) + if ((m_FoodLevel >= 18) && (GetHealth() < GetMaxHealth())) { // Regenerate health from food, incur 3 pts of food exhaustion: Heal(1); - m_FoodExhaustionLevel += 3.0; + AddFoodExhaustion(3.0); } else if ((m_FoodLevel <= 0) && (m_Health > 1)) { @@ -2000,20 +2027,9 @@ void cPlayer::HandleFood(void) } } } - - // Apply food exhaustion that has accumulated: - if (m_FoodExhaustionLevel >= 4.0) + else { - m_FoodExhaustionLevel -= 4.0; - - if (m_FoodSaturationLevel >= 1.0) - { - m_FoodSaturationLevel -= 1.0; - } - else - { - SetFoodLevel(m_FoodLevel - 1); - } + m_FoodTickTimer = 0; } } @@ -2088,14 +2104,17 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) else if (IsSubmerged()) { m_Stats.AddValue(statDistDove, Value); + AddFoodExhaustion(0.00015 * (double)Value); } else if (IsSwimming()) { m_Stats.AddValue(statDistSwum, Value); + AddFoodExhaustion(0.00015 * (double)Value); } else if (IsOnGround()) { m_Stats.AddValue(statDistWalked, Value); + AddFoodExhaustion((m_IsSprinting ? 0.001 : 0.0001) * (double)Value); } else { diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 65c1e33a8..f188789b8 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -284,10 +284,7 @@ public: bool Feed(int a_Food, double a_Saturation); /** Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. */ - void AddFoodExhaustion(double a_Exhaustion) - { - m_FoodExhaustionLevel += a_Exhaustion; - } + void AddFoodExhaustion(double a_Exhaustion); /** Starts the food poisoning for the specified amount of ticks */ void FoodPoison(int a_NumTicks); diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index ff1d7991b..98050cad8 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -33,29 +33,69 @@ public: case E_ITEM_BREAD: return FoodInfo(5, 6); // Carrots handled in ItemSeeds case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2); - case E_ITEM_COOKED_FISH: return FoodInfo(5, 6); + case E_ITEM_COOKED_FISH: return FoodInfo(5, 6); // TODO: Add other fish types case E_ITEM_COOKED_PORKCHOP: return FoodInfo(8, 12.8); case E_ITEM_COOKIE: return FoodInfo(2, 0.4); - case E_ITEM_GOLDEN_APPLE: return FoodInfo(4, 9.6); + // Golden apple handled in ItemGoldenApple case E_ITEM_GOLDEN_CARROT: return FoodInfo(6, 14.4); case E_ITEM_MELON_SLICE: return FoodInfo(2, 1.2); case E_ITEM_MUSHROOM_SOUP: return FoodInfo(6, 7.2); - case E_ITEM_POISONOUS_POTATO: return FoodInfo(2, 1.2, 60); + case E_ITEM_POISONOUS_POTATO: return FoodInfo(2, 1.2); // Potatoes handled in ItemSeeds case E_ITEM_PUMPKIN_PIE: return FoodInfo(8, 4.8); case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8); - case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2, 30); + case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2); case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2); case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8); case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); - case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8, 80); - case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2, 100); + case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8); + case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2); case E_ITEM_STEAK: return FoodInfo(8, 12.8); } LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType); return FoodInfo(0, 0.f); } - + + virtual bool GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_EffectDurationTicks, short & a_EffectIntensity, float & a_Chance) override + { + switch (m_ItemType) + { + case E_ITEM_RAW_CHICKEN: + { + a_EffectType = cEntityEffect::effHunger; + a_EffectDurationTicks = 600; + a_EffectIntensity = 0; + a_Chance = 0.3f; + return true; + } + case E_ITEM_ROTTEN_FLESH: + { + a_EffectType = cEntityEffect::effHunger; + a_EffectDurationTicks = 600; + a_EffectIntensity = 0; + a_Chance = 0.8f; + return true; + } + case E_ITEM_SPIDER_EYE: + { + a_EffectType = cEntityEffect::effPoison; + a_EffectDurationTicks = 100; + a_EffectIntensity = 0; + a_Chance = 1.0f; + return true; + } + case E_ITEM_POISONOUS_POTATO: + { + a_EffectType = cEntityEffect::effPoison; + a_EffectDurationTicks = 100; + a_EffectIntensity = 0; + a_Chance = 0.6f; + return true; + } + } + return false; + } + }; diff --git a/src/Items/ItemGoldenApple.h b/src/Items/ItemGoldenApple.h new file mode 100644 index 000000000..4e1096e65 --- /dev/null +++ b/src/Items/ItemGoldenApple.h @@ -0,0 +1,58 @@ +#pragma once + +#include "ItemFood.h" + + + + + +class cItemGoldenAppleHandler : + public cItemFoodHandler +{ + typedef cItemFoodHandler super; + +public: + cItemGoldenAppleHandler() + : super(E_ITEM_GOLDEN_APPLE) + { + } + + + virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override + { + // Feed the player: + FoodInfo Info = GetFoodInfo(); + a_Player->Feed(Info.FoodLevel, Info.Saturation); + + // Add the effects: + a_Player->AddEntityEffect(cEntityEffect::effAbsorption, 2400, 0); + a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 100, 1); + + // When the apple is a 'notch apple', give extra effects: + if (a_Item->m_ItemDamage > 0) + { + a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 600, 4); + a_Player->AddEntityEffect(cEntityEffect::effResistance, 6000, 0); + a_Player->AddEntityEffect(cEntityEffect::effFireResistance, 6000, 0); + } + + return true; + } + + + virtual FoodInfo GetFoodInfo(void) override + { + return FoodInfo(4, 9.6); + } + + + virtual bool GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_EffectDurationTicks, short & a_EffectIntensity, float & a_Chance) override + { + return false; + } + +}; + + + + diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index d36b5d663..c7cc682ca 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -25,6 +25,7 @@ #include "ItemFishingRod.h" #include "ItemFlowerPot.h" #include "ItemFood.h" +#include "ItemGoldenApple.h" #include "ItemItemFrame.h" #include "ItemHoe.h" #include "ItemLeaves.h" @@ -106,7 +107,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_BED: return new cItemBedHandler(a_ItemType); case E_ITEM_BOAT: return new cItemBoatHandler(a_ItemType); case E_ITEM_BOTTLE_O_ENCHANTING: return new cItemBottleOEnchantingHandler(); - case E_ITEM_BOW: return new cItemBowHandler; + case E_ITEM_BOW: return new cItemBowHandler(); case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType); case E_ITEM_CAKE: return new cItemCakeHandler(a_ItemType); case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType); @@ -120,6 +121,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType); + case E_ITEM_GOLDEN_APPLE: return new cItemGoldenAppleHandler(); case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType); case E_ITEM_MAP: return new cItemMapHandler(); case E_ITEM_MILK: return new cItemMilkHandler(); @@ -212,7 +214,6 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_COOKED_FISH: case E_ITEM_COOKED_PORKCHOP: case E_ITEM_COOKIE: - case E_ITEM_GOLDEN_APPLE: case E_ITEM_GOLDEN_CARROT: case E_ITEM_MELON_SLICE: case E_ITEM_MUSHROOM_SOUP: @@ -618,29 +619,39 @@ bool cItemHandler::GetPlacementBlockTypeMeta( +bool cItemHandler::GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_EffectDurationTicks, short & a_EffectIntensity, float & a_Chance) +{ + return false; +} + + + + + bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { UNUSED(a_Item); - - FoodInfo Info = GetFoodInfo(); + FoodInfo Info = GetFoodInfo(); if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) { bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation); - - // If consumed and there's chance of foodpoisoning, do it: - if (Success && (Info.PoisonChance > 0)) + + // Give effects + cEntityEffect::eType EffectType; + int EffectDurationTicks; + short EffectIntensity; + float Chance; + if (Success && GetEatEffect(EffectType, EffectDurationTicks, EffectIntensity, Chance)) { cFastRandom r1; - if ((r1.NextInt(100, a_Player->GetUniqueID()) - Info.PoisonChance) <= 0) + if (r1.NextFloat() < Chance) { - a_Player->FoodPoison(600); // Give the player food poisoning for 30 seconds. + a_Player->AddEntityEffect(EffectType, EffectDurationTicks, EffectIntensity, Chance); } } - return Success; } - return false; } diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index 1d5f59f3e..8b554ee34 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -3,6 +3,7 @@ #include "../Defines.h" #include "../Item.h" +#include "../Entities/EntityEffect.h" @@ -71,23 +72,24 @@ public: struct FoodInfo { - double Saturation; int FoodLevel; - int PoisonChance; // 0 - 100, in percent. 0 = no chance of poisoning, 100 = sure poisoning + double Saturation; FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) : - Saturation(a_Saturation), FoodLevel(a_FoodLevel), - PoisonChance(a_PoisonChance) + Saturation(a_Saturation) { } } ; - /** Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance) */ + /** Returns the FoodInfo for this item. (FoodRecovery and Saturation) */ virtual FoodInfo GetFoodInfo(); - + + /** If this function returns true, it sets the arguments to a effect who will be activated when you eat the item. */ + virtual bool GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_EffectDurationTicks, short & a_EffectIntensity, float & a_Chance); + /** Lets the player eat a selected item. Returns true if the player ate the item */ - virtual bool EatItem(cPlayer *a_Player, cItem *a_Item); + virtual bool EatItem(cPlayer * a_Player, cItem * a_Item); /** Indicates if this item is a tool */ virtual bool IsTool(void); -- cgit v1.2.3 From 87d195171a7069139cbbc9dfc2534ddd6c1ad867 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 23:08:08 +0200 Subject: Changed IsSolid to FullyOccupiesVoxel --- src/Blocks/BlockIce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index c085e9290..c38630fe3 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -32,7 +32,7 @@ public: } BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - if (!cBlockInfo::IsSolid(BlockBelow) && !IsBlockLava(BlockBelow) && !IsBlockWater(BlockBelow)) + if (!cBlockInfo::FullyOccupiesVoxel(BlockBelow) && !IsBlockLiquid(BlockBelow)) { return; } -- cgit v1.2.3 From cfaef0de386640fcc1729e6574fd481949bb6a3c Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 23:11:51 +0200 Subject: Capitalised "incremental" --- src/World.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index b247a79bc..7500b163d 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3176,17 +3176,17 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile) { - AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "incremental"); + AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental"); if (SimulatorName.empty()) { - LOGWARNING("[Physics] RedstoneSimulator not present or empty in %s, using the default of \"incremental\".", GetIniFileName().c_str()); - SimulatorName = "incremental"; + LOGWARNING("[Physics] RedstoneSimulator not present or empty in %s, using the default of \"Incremental\".", GetIniFileName().c_str()); + SimulatorName = "Incremental"; } cRedstoneSimulator * res = NULL; - if (NoCaseCompare(SimulatorName, "incremental") == 0) + if (NoCaseCompare(SimulatorName, "Incremental") == 0) { res = new cIncrementalRedstoneSimulator(*this); } -- cgit v1.2.3 From 09b63565bcdd5977988d390f33de47b17cc7b7b7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 23:19:05 +0200 Subject: Use "default:" in switch. --- src/BlockEntities/BeaconEntity.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 55c5ccb7f..805e5e61f 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -73,10 +73,13 @@ bool cBeaconEntity::IsValidEffect(cEntityEffect::eType a_Effect, char a_BeaconLe case cEntityEffect::effSpeed: return (a_BeaconLevel >= 1); case cEntityEffect::effHaste: return (a_BeaconLevel >= 1); case cEntityEffect::effNoEffect: return true; - } - LOGD("%s: Invalid beacon effect: %d", __FUNCTION__, (int)a_Effect); - return false; + default: + { + LOGD("%s: Invalid beacon effect: %d", __FUNCTION__, (int)a_Effect); + return false; + } + } } -- cgit v1.2.3 From 160fa3a9a9466da646bc7631543e813690f5a77d Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 31 Jul 2014 23:56:49 +0200 Subject: Import Statistics.h --- src/ClientHandle.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index bd76ef227..79ec8c9b6 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -3,6 +3,7 @@ #include "ClientHandle.h" #include "Server.h" #include "World.h" +#include "Statistics.h" #include "Entities/Pickup.h" #include "Bindings/PluginManager.h" #include "Entities/Player.h" -- cgit v1.2.3 From 86d84bcb7391b6a862b53436623b97140529aa83 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 1 Aug 2014 17:29:17 +0200 Subject: Compile fix. --- src/ClientHandle.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 79ec8c9b6..2d665a06c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -3,7 +3,6 @@ #include "ClientHandle.h" #include "Server.h" #include "World.h" -#include "Statistics.h" #include "Entities/Pickup.h" #include "Bindings/PluginManager.h" #include "Entities/Player.h" @@ -635,7 +634,7 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, if (!m_Player->IsSwimming()) { - m_Player->GetStatManager().AddValue(eStatistic::statJumps, 1); + m_Player->GetStatManager().AddValue(statJumps, 1); m_Player->AddFoodExhaustion(m_Player->IsSprinting() ? 0.8 : 0.2); } } -- cgit v1.2.3 From bfe11024ac9bf202baa49a88d9370738ab0fcb8b Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 1 Aug 2014 19:37:08 +0200 Subject: Added missing HOOK_BLOCK_SPREAD call. --- src/Simulator/FireSimulator.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 69dc7164e..cdb5abde2 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -359,18 +359,26 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel continue; } + int AbsX = (Neighbour->GetPosX() * cChunkDef::Width) + X; + int Y = a_RelY + gNeighborCoords[i].y; + int AbsZ = (Neighbour->GetPosZ() * cChunkDef::Width) + Z; + if (BlockType == E_BLOCK_TNT) { - int AbsX = X + Neighbour->GetPosX() * cChunkDef::Width; - int AbsZ = Z + Neighbour->GetPosZ() * cChunkDef::Width; - - m_World.SpawnPrimedTNT(AbsX, a_RelY + gNeighborCoords[i].y, AbsZ, 0); - Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, E_BLOCK_AIR, 0); + m_World.SpawnPrimedTNT(AbsX, Y, AbsZ, 0); + Neighbour->SetBlock(X, a_RelY + Y, Z, E_BLOCK_AIR, 0); return; } bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance); - Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0); + if (ShouldReplaceFuel && !cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, AbsX, Y, AbsZ, ssFireSpread)) + { + Neighbour->SetBlock(X, Y, Z, E_BLOCK_FIRE, 0); + } + else + { + Neighbour->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); + } } // for i - Coords[] } -- cgit v1.2.3 From c865fc8ca501e7405da2ce8353628373e4526053 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 1 Aug 2014 22:05:40 +0100 Subject: Improved endermen code a little --- src/Mobs/Enderman.cpp | 68 +++++++++++++++++++++++++++++++++++++-------------- src/Mobs/Enderman.h | 4 +++ src/Mobs/Monster.cpp | 4 ++- 3 files changed, 56 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index a32e4e175..1dc73d654 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -14,9 +14,10 @@ class cPlayerLookCheck : public cPlayerListCallback { public: - cPlayerLookCheck(Vector3d a_EndermanPos) : + cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) : m_Player(NULL), - m_EndermanPos(a_EndermanPos) + m_EndermanPos(a_EndermanPos), + m_SightDistance(a_SightDistance) { } @@ -30,8 +31,8 @@ public: Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); - // Don't check players who are more then 64 blocks away - if (Direction.SqrLength() > 64) + // Don't check players who are more then SightDistance (64) blocks away + if (Direction.Length() > m_SightDistance) { return false; } @@ -48,7 +49,7 @@ public: // 0.09 rad ~ 5 degrees // If the player's crosshair is within 5 degrees of the enderman, it counts as looking - if (dot > cos(0.09)) + if (dot <= cos(0.09)) { return false; } @@ -69,6 +70,7 @@ public: protected: cPlayer * m_Player; Vector3d m_EndermanPos; + int m_SightDistance; } ; @@ -107,7 +109,7 @@ void cEnderman::CheckEventSeePlayer() return; } - cPlayerLookCheck Callback(GetPosition()); + cPlayerLookCheck Callback(GetPosition(), m_SightDistance); if (m_World->ForEachPlayer(Callback)) { return; @@ -115,20 +117,10 @@ void cEnderman::CheckEventSeePlayer() ASSERT(Callback.GetPlayer() != NULL); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); - - // Check if the chunk the enderman is in is lit - if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) - { - m_World->QueueLightChunk(ChunkX, ChunkZ); - return; - } - - // Enderman only attack if the skylight is higher than 7 - if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) <= 7) + if (!CheckLight()) { - // TODO: Teleport the enderman to a random spot + // Insufficient light for enderman to become aggravated + // TODO: Teleport to a suitable location return; } @@ -140,6 +132,19 @@ void cEnderman::CheckEventSeePlayer() GetWorld()->BroadcastEntityMetadata(*this); } } + + + + + +void cEnderman::CheckEventLostPlayer(void) +{ + super::CheckEventLostPlayer(); + if (!CheckLight()) + { + EventLosePlayer(); + } +} @@ -151,3 +156,28 @@ void cEnderman::EventLosePlayer() m_bIsScreaming = false; GetWorld()->BroadcastEntityMetadata(*this); } + + + + + +bool cEnderman::CheckLight() +{ + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); + + // Check if the chunk the enderman is in is lit + if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) + { + m_World->QueueLightChunk(ChunkX, ChunkZ); + return true; + } + + // Enderman only attack if the skylight is lower or equal to 8 + if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() > 8) + { + return false; + } + + return true; +} diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index da857ee09..4583746e7 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -19,12 +19,16 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void CheckEventSeePlayer(void) override; + virtual void CheckEventLostPlayer(void) override; virtual void EventLosePlayer(void) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } NIBBLETYPE GetCarriedMeta(void) const {return CarriedMeta; } + /** Returns if the current sky light level is sufficient for the enderman to become aggravated */ + bool CheckLight(void); + private: bool m_bIsScreaming; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 622a67816..94df991a3 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -276,7 +276,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) if (DoesPosYRequireJump((int)floor(m_Destination.y))) { m_bOnGround = false; - AddSpeedY(5.2); // Jump!! + + // TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport + AddPosY(1.2); // Jump!! } } -- cgit v1.2.3 From b5c0a4aa3ac904a7db1ee23e92a73dad6e1d4ade Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 1 Aug 2014 22:15:14 +0100 Subject: Fixed issues with autocomplete and time loading * Fixes #1274 --- src/World.cpp | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 865ddfcc6..d2213d1e5 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -578,8 +578,7 @@ void cWorld::Start(void) m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); int GameMode = IniFile.GetValueSetI("General", "Gamemode", (int)m_GameMode); int Weather = IniFile.GetValueSetI("General", "Weather", (int)m_Weather); - m_TimeOfDay = IniFile.GetValueSetI("General", "TimeInTicks", m_TimeOfDay); - + if (GetDimension() == dimOverworld) { m_NetherWorldName = IniFile.GetValueSet("LinkedWorlds", "NetherWorldName", GetName() + "_nether"); @@ -597,6 +596,7 @@ void cWorld::Start(void) InitialiseGeneratorDefaults(IniFile); InitialiseAndLoadMobSpawningValues(IniFile); + SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", m_TimeOfDay)); m_ChunkMap = new cChunkMap(this); @@ -3153,21 +3153,47 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Results) { + typedef std::pair pair_t; + size_t LastSpace = a_Text.find_last_of(" "); // Find the position of the last space + AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); // Find the last word + + if (LastWord.empty()) + { + return; + } + + std::vector UsernamesByWeight; + cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { - size_t LastSpace = a_Text.find_last_of(" "); // Find the position of the last space - - AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); // Find the last word AString PlayerName ((*itr)->GetName()); - size_t Found = PlayerName.find(LastWord); // Try to find last word in playername + AString::size_type Found = PlayerName.find(LastWord); // Try to find last word in playername if (Found == AString::npos) { continue; // No match } - a_Results.push_back(PlayerName); // Match! + UsernamesByWeight.push_back(std::make_pair(Found, PlayerName)); // Match! Store it with the position of the match as a weight + } + Lock.Unlock(); + + std::sort(UsernamesByWeight.begin(), UsernamesByWeight.end()); // Sort lexicographically (by the first value, then second), so higher weights (usernames with match closer to start) come first (#1274) + + /* TODO: Uncomment once migrated to C++11 + std::transform( + UsernamesByWeight.begin(), + UsernamesByWeight.end(), + std::back_inserter(a_Results), + [](const pair_t & p) { return p.first; } + ); + */ + + a_Results.reserve(UsernamesByWeight.size()); + for (std::vector::const_iterator itr = UsernamesByWeight.begin(); itr != UsernamesByWeight.end(); ++itr) + { + a_Results.push_back(itr->second); } } -- cgit v1.2.3 From 3b4255dbfe6dc0fa2ecd861221a2ed5b124a81ad Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 2 Aug 2014 00:14:05 +0200 Subject: Fixed a bug who can used from hacked clients. --- src/BlockEntities/BeaconEntity.cpp | 2 ++ src/ClientHandle.cpp | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index 805e5e61f..dcf659f47 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -90,6 +90,7 @@ bool cBeaconEntity::SetPrimaryEffect(cEntityEffect::eType a_Effect) { if (!IsValidEffect(a_Effect, m_BeaconLevel)) { + m_PrimaryEffect = cEntityEffect::effNoEffect; return false; } @@ -111,6 +112,7 @@ bool cBeaconEntity::SetSecondaryEffect(cEntityEffect::eType a_Effect) { if (!IsValidEffect(a_Effect, m_BeaconLevel)) { + m_SecondaryEffect = cEntityEffect::effNoEffect; return false; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d71c6a9d8..72257028a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -795,7 +795,22 @@ void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) Window->SetSlot(*m_Player, 0, cItem()); BeaconWindow->GetBeaconEntity()->SetPrimaryEffect(PrimaryEffect); - BeaconWindow->GetBeaconEntity()->SetSecondaryEffect(SecondaryEffect); + + // Valid effect check. Vanilla don't check this, but we do it :) + if ( + (SecondaryEffect == cEntityEffect::effNoEffect) || + (SecondaryEffect == cEntityEffect::effRegeneration) || + (SecondaryEffect == BeaconWindow->GetBeaconEntity()->GetPrimaryEffect()) + ) + { + BeaconWindow->GetBeaconEntity()->SetSecondaryEffect(SecondaryEffect); + } + else + { + BeaconWindow->GetBeaconEntity()->SetSecondaryEffect(cEntityEffect::effNoEffect); + } + + m_Player->CloseWindow(true); } -- cgit v1.2.3 From a44fbf2338e98e81bbc55780c92fa8780b061f9f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 2 Aug 2014 21:44:16 +0200 Subject: Added proper trees and height for SwamplandM biome --- src/Generating/HeiGen.cpp | 2 +- src/Generating/Trees.cpp | 2 +- src/Generating/Trees.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 870ceef7f..ba11b31b4 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -432,7 +432,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131 /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132 /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133 - /* biSwamplandM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 134 + /* biSwamplandM */ { 1.0f, 2.0f, 1.10f, 5.0f, 0.01f, 8.0f, 60}, // 134 // Biomes 135 .. 139 unused, 5 empty placeholders here: {}, {}, {}, {}, {}, // 135 .. 139 diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 32594d0b4..1b0f2dc14 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -181,6 +181,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No return; } + case biSwamplandM: case biSwampland: { // Swamp trees: @@ -233,7 +234,6 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No case biExtremeHillsM: case biFlowerForest: case biTaigaM: - case biSwamplandM: case biIcePlainsSpikes: case biJungleM: case biJungleEdgeM: diff --git a/src/Generating/Trees.h b/src/Generating/Trees.h index 1f6ac4dff..c9eb7de80 100644 --- a/src/Generating/Trees.h +++ b/src/Generating/Trees.h @@ -28,6 +28,7 @@ logs can overwrite others(leaves), but others shouldn't overwrite logs. This is #define CASE_TREE_ALLOWED_BLOCKS \ case E_BLOCK_AIR: \ case E_BLOCK_LEAVES: \ + case E_BLOCK_NEW_LEAVES: \ case E_BLOCK_SNOW: \ case E_BLOCK_TALL_GRASS: \ case E_BLOCK_DEAD_BUSH: \ @@ -40,6 +41,7 @@ logs can overwrite others(leaves), but others shouldn't overwrite logs. This is /* case E_BLOCK_LEAVES: LEAVES are a special case, they can be overwritten only by log. Handled in cChunkMap::ReplaceTreeBlocks(). */ \ case E_BLOCK_SNOW: \ case E_BLOCK_TALL_GRASS: \ + case E_BLOCK_BIG_FLOWER: \ case E_BLOCK_DEAD_BUSH: \ case E_BLOCK_SAPLING: \ case E_BLOCK_VINES -- cgit v1.2.3 From 7915c4ca7cf4a7afaa86e62757d23364ead4c69e Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 2 Aug 2014 21:44:02 -0700 Subject: Entity.cpp: On portal check, use if-else for current dimension If current dimension corresponds with the portal (nether portal in the nether) send to the overworld, else send to the portal dimension. No need to switch on the dimension and exclude potential others. --- src/Entities/Entity.cpp | 114 +++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index da578013d..c2727e6a1 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1068,42 +1068,38 @@ bool cEntity::DetectPortal() } m_PortalCooldownData.m_TicksDelayed = 0; - switch (GetWorld()->GetDimension()) + if (GetWorld()->GetDimension() == dimNether) { - case dimNether: + if (GetWorld()->GetLinkedOverworldName().empty()) { - if (GetWorld()->GetLinkedOverworldName().empty()) - { - return false; - } - - m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn - - if (IsPlayer()) - { - ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); // Send a respawn packet before world is loaded/generated so the client isn't left in limbo - } - - return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + return false; } - case dimOverworld: + + m_PortalCooldownData.m_ShouldPreventTeleportation = true; // Stop portals from working on respawn + + if (IsPlayer()) + { + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimOverworld); // Send a respawn packet before world is loaded/generated so the client isn't left in limbo + } + + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + } + else + { + if (GetWorld()->GetNetherWorldName().empty()) + { + return false; + } + + m_PortalCooldownData.m_ShouldPreventTeleportation = true; + + if (IsPlayer()) { - if (GetWorld()->GetNetherWorldName().empty()) - { - return false; - } - - m_PortalCooldownData.m_ShouldPreventTeleportation = true; - - if (IsPlayer()) - { - ((cPlayer *)this)->AwardAchievement(achEnterPortal); - ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether); - } - - return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); + ((cPlayer *)this)->AwardAchievement(achEnterPortal); + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimNether); } - default: return false; + + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetNetherWorldName(), dimNether, GetWorld()->GetName()), false); } } case E_BLOCK_END_PORTAL: @@ -1113,45 +1109,43 @@ bool cEntity::DetectPortal() return false; } - switch (GetWorld()->GetDimension()) + if (GetWorld()->GetDimension() == dimEnd) { - case dimEnd: + + if (GetWorld()->GetLinkedOverworldName().empty()) { - if (GetWorld()->GetLinkedOverworldName().empty()) - { - return false; - } - - m_PortalCooldownData.m_ShouldPreventTeleportation = true; + return false; + } - if (IsPlayer()) - { - cPlayer * Player = (cPlayer *)this; - Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); - Player->GetClientHandle()->SendRespawn(dimOverworld); - } + m_PortalCooldownData.m_ShouldPreventTeleportation = true; - return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); - } - case dimOverworld: + if (IsPlayer()) { - if (GetWorld()->GetEndWorldName().empty()) - { - return false; - } + cPlayer * Player = (cPlayer *)this; + Player->TeleportToCoords(Player->GetLastBedPos().x, Player->GetLastBedPos().y, Player->GetLastBedPos().z); + Player->GetClientHandle()->SendRespawn(dimOverworld); + } - m_PortalCooldownData.m_ShouldPreventTeleportation = true; + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetLinkedOverworldName()), false); + } + else + { + if (GetWorld()->GetEndWorldName().empty()) + { + return false; + } - if (IsPlayer()) - { - ((cPlayer *)this)->AwardAchievement(achEnterTheEnd); - ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd); - } + m_PortalCooldownData.m_ShouldPreventTeleportation = true; - return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); + if (IsPlayer()) + { + ((cPlayer *)this)->AwardAchievement(achEnterTheEnd); + ((cPlayer *)this)->GetClientHandle()->SendRespawn(dimEnd); } - default: return false; + + return MoveToWorld(cRoot::Get()->CreateAndInitializeWorld(GetWorld()->GetEndWorldName(), dimEnd, GetWorld()->GetName()), false); } + } default: break; } -- cgit v1.2.3 From 3ffec92e7930c0b4bb14073f23a9d12313bd6cbc Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 2 Aug 2014 22:27:27 -0700 Subject: Removed unused cPlayer::FoodPoison function --- src/Entities/Player.cpp | 9 --------- src/Entities/Player.h | 3 --- 2 files changed, 12 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ca3b1f367..d3d5a61d4 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -580,15 +580,6 @@ void cPlayer::AddFoodExhaustion(double a_Exhaustion) -void cPlayer::FoodPoison(int a_NumTicks) -{ - AddEntityEffect(cEntityEffect::effHunger, a_NumTicks, 0, 1); -} - - - - - void cPlayer::StartEating(void) { // Set the timer: diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 917e87a89..e3203d6d1 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -286,9 +286,6 @@ public: /** Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. */ void AddFoodExhaustion(double a_Exhaustion); - /** Starts the food poisoning for the specified amount of ticks */ - void FoodPoison(int a_NumTicks); - /** Returns true if the player is currently in the process of eating the currently equipped item */ bool IsEating(void) const { return (m_EatingFinishTick >= 0); } -- cgit v1.2.3 From 9ecce2366e81ae66c77312220e378ff2f1b02a24 Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 2 Aug 2014 22:35:29 -0700 Subject: Code reduction and clarity fixes --- src/Entities/Entity.cpp | 28 +++++++++------------------- src/Entities/Player.cpp | 17 +++++++---------- 2 files changed, 16 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index c2727e6a1..042e3b868 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -543,10 +543,7 @@ void cEntity::KilledBy(TakeDamageInfo & a_TDI) void cEntity::Heal(int a_HitPoints) { m_Health += a_HitPoints; - if (m_Health > m_MaxHealth) - { - m_Health = m_MaxHealth; - } + m_Health = std::min(m_Health, m_MaxHealth); } @@ -555,7 +552,7 @@ void cEntity::Heal(int a_HitPoints) void cEntity::SetHealth(int a_Health) { - m_Health = std::max(0, std::min(m_MaxHealth, a_Health)); + m_Health = Clamp(a_Health, 0, m_MaxHealth); } @@ -1264,10 +1261,10 @@ void cEntity::HandleAir(void) SetSpeedY(1); // Float in the water } - // Either reduce air level or damage player - if (m_AirLevel < 1) + if (m_AirLevel <= 0) { - if (m_AirTickTimer < 1) + // Either reduce air level or damage player + if (m_AirTickTimer <= 0) { // Damage player TakeDamage(dtDrowning, NULL, 1, 1, 0); @@ -1552,17 +1549,10 @@ void cEntity::SetHeight(double a_Height) void cEntity::SetMass(double a_Mass) { - if (a_Mass > 0) - { - m_Mass = a_Mass; - } - else - { - // Make sure that mass is not zero. 1g is the default because we - // have to choose a number. It's perfectly legal to have a mass - // less than 1g as long as is NOT equal or less than zero. - m_Mass = 0.001; - } + // Make sure that mass is not zero. 1g is the default because we + // have to choose a number. It's perfectly legal to have a mass + // less than 1g as long as is NOT equal or less than zero. + m_Mass = std::max(a_Mass, 0.001); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index d3d5a61d4..d1d7349a6 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -527,7 +527,7 @@ void cPlayer::SetFoodLevel(int a_FoodLevel) void cPlayer::SetFoodSaturationLevel(double a_FoodSaturationLevel) { - m_FoodSaturationLevel = std::max(0.0, std::min(a_FoodSaturationLevel, (double)m_FoodLevel)); + m_FoodSaturationLevel = Clamp(a_FoodSaturationLevel, 0.0, (double) m_FoodLevel); } @@ -545,7 +545,7 @@ void cPlayer::SetFoodTickTimer(int a_FoodTickTimer) void cPlayer::SetFoodExhaustionLevel(double a_FoodExhaustionLevel) { - m_FoodExhaustionLevel = std::max(0.0, std::min(a_FoodExhaustionLevel, 40.0)); + m_FoodExhaustionLevel = Clamp(a_FoodExhaustionLevel, 0.0, 40.0); } @@ -700,16 +700,13 @@ double cPlayer::GetMaxSpeed(void) const { return m_FlyingMaxSpeed; } + else if (m_IsSprinting) + { + return m_SprintingMaxSpeed; + } else { - if (m_IsSprinting) - { - return m_SprintingMaxSpeed; - } - else - { - return m_NormalMaxSpeed; - } + return m_NormalMaxSpeed; } } -- cgit v1.2.3 From e461df00302939cd767ae0c6a31ce22fc94e977c Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 3 Aug 2014 02:20:48 -0700 Subject: Entity.cpp: Air timer comment fix --- src/Entities/Entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 042e3b868..a274e6780 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1263,7 +1263,7 @@ void cEntity::HandleAir(void) if (m_AirLevel <= 0) { - // Either reduce air level or damage player + // Runs the air tick timer to check whether the player should be damaged if (m_AirTickTimer <= 0) { // Damage player -- cgit v1.2.3 From dd9a19e3952ce48fe8d3ad4825889f17c69ac55a Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 3 Aug 2014 15:31:59 +0200 Subject: VillageGen: Fixed a typo in comment --- src/Generating/VillageGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index cade923c9..a7f66b75e 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -168,7 +168,7 @@ protected: /** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */ int m_Density; - /** Borders of the vilalge - no item may reach out of this cuboid. */ + /** Borders of the village - no item may reach out of this cuboid. */ cCuboid m_Borders; /** Prefabs to use for buildings */ -- cgit v1.2.3 From 6ce61d1a6fd912c99284875a9052475e06fba432 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 11:57:05 +0200 Subject: Fixed a ToLua warning - operator = not supported. --- src/BlockID.cpp | 2 +- src/Cuboid.cpp | 2 +- src/Cuboid.h | 6 +++++- src/Entities/EntityEffect.cpp | 2 +- src/Entities/EntityEffect.h | 2 +- src/Globals.h | 4 ++-- src/Matrix4.h | 4 ++++ src/WorldStorage/WorldStorage.h | 2 +- 8 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/BlockID.cpp b/src/BlockID.cpp index d145a2e5b..07a1fc9e5 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -17,7 +17,7 @@ class cBlockIDMap // Making the map case-insensitive: struct Comparator { - bool operator()(const AString & a_Item1, const AString & a_Item2) const + bool operator ()(const AString & a_Item1, const AString & a_Item2) const { return (NoCaseCompare(a_Item1, a_Item2) > 0); } diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index 26e86c77b..8891cfcb1 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -24,7 +24,7 @@ static bool DoIntervalsIntersect(int a_Min1, int a_Max1, int a_Min2, int a_Max2) //////////////////////////////////////////////////////////////////////////////// // cCuboid: -cCuboid & cCuboid::operator=(cCuboid a_Other) +cCuboid & cCuboid::operator =(cCuboid a_Other) { std::swap(p1, a_Other.p1); std::swap(p2, a_Other.p2); diff --git a/src/Cuboid.h b/src/Cuboid.h index d62cf8063..c205156ec 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -20,7 +20,11 @@ public: cCuboid(int a_X1, int a_Y1, int a_Z1) : p1(a_X1, a_Y1, a_Z1), p2(a_X1, a_Y1, a_Z1) {} cCuboid(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) : p1(a_X1, a_Y1, a_Z1), p2(a_X2, a_Y2, a_Z2) {} - cCuboid & operator=(cCuboid a_Other); + // tolua_end + + cCuboid & operator =(cCuboid a_Other); + + // tolua_begin void Assign(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2); void Assign(const cCuboid & a_SrcCuboid); diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 39314f256..3e28392f4 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -170,7 +170,7 @@ cEntityEffect::cEntityEffect(const cEntityEffect & a_OtherEffect): -cEntityEffect & cEntityEffect::operator=(cEntityEffect a_OtherEffect) +cEntityEffect & cEntityEffect::operator =(cEntityEffect a_OtherEffect) { std::swap(m_Ticks, a_OtherEffect.m_Ticks); std::swap(m_Duration, a_OtherEffect.m_Duration); diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h index f9c1e4eb2..47c298f57 100644 --- a/src/Entities/EntityEffect.h +++ b/src/Entities/EntityEffect.h @@ -71,7 +71,7 @@ public: /** Creates an entity effect by copying another @param a_OtherEffect The other effect to copy */ - cEntityEffect & operator=(cEntityEffect a_OtherEffect); + cEntityEffect & operator =(cEntityEffect a_OtherEffect); virtual ~cEntityEffect(void) {} diff --git a/src/Globals.h b/src/Globals.h index b35af9604..60ee456c9 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -156,11 +156,11 @@ template class SizeChecker; template class SizeChecker; template class SizeChecker; -// A macro to disallow the copy constructor and operator= functions +// A macro to disallow the copy constructor and operator = functions // This should be used in the private: declarations for any class that shouldn't allow copying itself #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName &); \ - void operator=(const TypeName &) + void operator =(const TypeName &) // A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc #define UNUSED(X) (void)(X) diff --git a/src/Matrix4.h b/src/Matrix4.h index 081847b9f..61ea60bfd 100644 --- a/src/Matrix4.h +++ b/src/Matrix4.h @@ -34,6 +34,8 @@ public: { *this = a_Rhs; } + + // tolua_end inline Matrix4 & operator = (const Matrix4 & a_Rhs) { @@ -43,6 +45,8 @@ public: } return *this; } + + // tolua_begin inline T & operator [] (int a_N) { diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index 978a5b5d1..5d8aa4589 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -93,7 +93,7 @@ protected: sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} - bool operator==(const sChunkLoad other) const + bool operator ==(const sChunkLoad other) const { return this->m_ChunkX == other.m_ChunkX && this->m_ChunkY == other.m_ChunkY && -- cgit v1.2.3 From 836de13797577289e91478ce89de65d39096f9e4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 11:57:26 +0200 Subject: Added cPlayer::GetUUID(). --- src/Entities/Player.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index e3203d6d1..e26808bfc 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -417,6 +417,9 @@ public: /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } + + /** Returns the UUID (short format) that has been read from the client, or empty string if not available. */ + const AString & GetUUID(void) const { return m_UUID; } // tolua_end -- cgit v1.2.3 From 003f18bd0f7593bddf5c6af89e3f6fc13632300d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 12:12:28 +0200 Subject: Added cMojangAPI:GetUUIDFromPlayerName(). This is a simpler way to ask for a single name -> uuid conversion. --- src/Protocol/MojangAPI.cpp | 28 ++++++++++++++++++++++++++++ src/Protocol/MojangAPI.h | 7 +++++++ 2 files changed, 35 insertions(+) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 45baa5a4f..f53df1cba 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -129,6 +129,34 @@ void cMojangAPI::Start(cIniFile & a_SettingsIni) +AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached) +{ + // Convert the playername to lowercase: + AString lcPlayerName(a_PlayerName); + StrToLower(lcPlayerName); + + // Request the cache to populate any names not yet contained: + if (!a_UseOnlyCached) + { + AStringVector PlayerNames; + PlayerNames.push_back(lcPlayerName); + CacheNamesToUUIDs(PlayerNames); + } + + // Retrieve from cache: + cNameToUUIDMap::const_iterator itr = m_NameToUUID.find(lcPlayerName); + if (itr == m_NameToUUID.end()) + { + // No UUID found + return ""; + } + return itr->second.m_PlayerName; +} + + + + + AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached) { // Convert all playernames to lowercase: diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index ac8995bb5..7f3ef4e39 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -45,6 +45,13 @@ public: Note: only checks the string's length, not the actual content. */ static AString MakeUUIDDashed(const AString & a_UUID); + /** Converts a player name into a UUID. + The UUID will be empty on error. + If a_UseOnlyCached is true, the function only consults the cached values. + If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking + operation, do not use this in world-tick thread! */ + AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false); + // tolua_end /** Converts the player names into UUIDs. -- cgit v1.2.3 From 98a13d97b3c913a7601b6c69c302f10b61851501 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 21:31:04 +0200 Subject: Trailing whitespace fix. --- src/Mobs/Enderman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 1dc73d654..0a1b6491a 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -103,7 +103,7 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cEnderman::CheckEventSeePlayer() -{ +{ if (m_Target != NULL) { return; -- cgit v1.2.3 From 21f52676f3848d58ff1e4eb511c691d4a4ed824b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 21:32:20 +0200 Subject: cMojangAPI: Added UUID-to-Name lookup. Also fixed the bindings, now all functions are static-like. --- src/Bindings/ManualBindings.cpp | 98 +++++++++- src/Protocol/Authenticator.cpp | 4 +- src/Protocol/MojangAPI.cpp | 383 +++++++++++++++++++++++++++++++++++----- src/Protocol/MojangAPI.h | 97 ++++++++-- src/Root.h | 2 +- 5 files changed, 522 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 34f0d7e30..042ffb19e 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2158,6 +2158,99 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L) +static int tolua_cMojangAPI_AddPlayerNameToUUIDMapping(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cMojangAPI") || + !S.CheckParamString(2) || + !S.CheckParamString(3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Retrieve the parameters: + AString UUID, PlayerName; + S.GetStackValue(2, PlayerName); + S.GetStackValue(3, UUID); + + // Store in the cache: + cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(PlayerName, UUID); + return 0; +} + + + + + +static int tolua_cMojangAPI_GetPlayerNameFromUUID(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cMojangAPI") || + !S.CheckParamString(2) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + AString UUID; + S.GetStackValue(2, UUID); + + // If the UseOnlyCached param was given, read it; default to false + bool ShouldUseCacheOnly = false; + if (lua_gettop(L) == 3) + { + ShouldUseCacheOnly = (lua_toboolean(L, 3) != 0); + lua_pop(L, 1); + } + + // Return the PlayerName: + AString PlayerName = cRoot::Get()->GetMojangAPI().GetPlayerNameFromUUID(UUID, ShouldUseCacheOnly); + S.Push(PlayerName); + return 1; +} + + + + + +static int tolua_cMojangAPI_GetUUIDFromPlayerName(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cMojangAPI") || + !S.CheckParamString(2) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + AString PlayerName; + S.GetStackValue(2, PlayerName); + + // If the UseOnlyCached param was given, read it; default to false + bool ShouldUseCacheOnly = false; + if (lua_gettop(L) == 3) + { + ShouldUseCacheOnly = (lua_toboolean(L, 3) != 0); + lua_pop(L, 1); + } + + // Return the UUID: + AString UUID = cRoot::Get()->GetMojangAPI().GetUUIDFromPlayerName(PlayerName, ShouldUseCacheOnly); + S.Push(UUID); + return 1; +} + + + + + static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) { cLuaState S(L); @@ -3158,7 +3251,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cMojangAPI"); - tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cMojangAPI_GetUUIDsFromPlayerNames); + tolua_function(tolua_S, "AddPlayerNameToUUIDMapping", tolua_cMojangAPI_AddPlayerNameToUUIDMapping); + tolua_function(tolua_S, "GetPlayerNameFromUUID", tolua_cMojangAPI_GetPlayerNameFromUUID); + tolua_function(tolua_S, "GetUUIDFromPlayerName", tolua_cMojangAPI_GetUUIDFromPlayerName); + tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cMojangAPI_GetUUIDsFromPlayerNames); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cItemGrid"); diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 160564d51..984000795 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -191,8 +191,8 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString()); a_Properties = root["properties"]; - // Store the player's UUID in the NameToUUID map in MojangAPI: - cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(a_UserName, a_UUID); + // Store the player's profile in the MojangAPI caches: + cRoot::Get()->GetMojangAPI().AddPlayerProfile(a_UserName, a_UUID, a_Properties); return true; } diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index f53df1cba..9fdf07380 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -25,8 +25,10 @@ const int MAX_PER_QUERY = 100; -#define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" -#define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" +#define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" +#define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" +#define DEFAULT_UUID_TO_PROFILE_SERVER "sessionserver.mojang.com" +#define DEFAULT_UUID_TO_PROFILE_ADDRESS "/session/minecraft/profile/%UUID%?unsigned=false" @@ -96,12 +98,66 @@ static const AString & StarfieldCACert(void) +//////////////////////////////////////////////////////////////////////////////// +// cMojangAPI::sProfile: + +cMojangAPI::sProfile::sProfile( + const AString & a_PlayerName, + const AString & a_UUID, + const Json::Value & a_Properties, + Int64 a_DateTime +) : + m_PlayerName(a_PlayerName), + m_UUID(a_UUID), + m_Textures(), + m_TexturesSignature(), + m_DateTime(a_DateTime) +{ + /* + Example a_Profile contents: + "properties": + [ + { + "name": "textures", + "value": "eyJ0aW1lc3RhbXAiOjE0MDcwNzAzMjEyNzEsInByb2ZpbGVJZCI6ImIxY2FmMjQyMDJhODQxYTc4MDU1YTA3OWM0NjBlZWU3IiwicHJvZmlsZU5hbWUiOiJ4b2Z0IiwiaXNQdWJsaWMiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9iNzc5YmFiZjVhNTg3Zjk0OGFkNjc0N2VhOTEyNzU0MjliNjg4Mjk1YWUzYzA3YmQwZTJmNWJmNGQwNTIifX19", + "signature": "XCty+jGEF39hEPrPhYNnCX087kPaoCjYruzYI/DS4nkL5hbjnkSM5Rh15hnUyv/FHhC8OF5rif3D1tQjtMI19KSVaXoUFXpbJM8/+PB8GDgEbX8Fc3u9nYkzOcM/xfxdYsFAdFhLQMkvase/BZLSuPhdy9DdI+TCrO7xuSTZfYmmwVuWo3w5gCY+mSIAnqltnOzaOOTcly75xvO0WYpVk7nJdnR2tvSi0wfrQPDrIg/uzhX7p0SnDqijmBU4QaNez/TNKiFxy69dAzt0RSotlQzqkDbyVKhhv9a4eY8h3pXi4UMftKEj4FAKczxLImkukJXuOn5NN15/Q+le0rJVBC60/xjKIVzltEsMN6qjWD0lQjey7WEL+4pGhCVuWY5KzuZjFvgqszuJTFz7lo+bcHiceldJtea8/fa02eTRObZvdLxbWC9ZfFY0IhpOVKfcLdno/ddDMNMQMi5kMrJ8MZZ/PcW1w5n7MMGWPGCla1kOaC55AL0QYSMGRVEZqgU9wXI5M7sHGZKGM4mWxkbEJYBkpI/p3GyxWgV6v33ZWlsz65TqlNrR1gCLaoFCm7Sif8NqPBZUAONHYon0roXhin/DyEanS93WV6i6FC1Wisscjq2AcvnOlgTo/5nN/1QsMbjNumuMGo37sqjRqlXoPb8zEUbAhhztYuJjEfQ2Rd8=" + } + ] + */ + + // Parse the Textures and TexturesSignature from the Profile: + if (!a_Properties.isArray()) + { + // Properties is not a valid array, bail out + return; + } + Json::UInt Size = a_Properties.size(); + for (Json::UInt i = 0; i < Size; i++) + { + const Json::Value & Prop = a_Properties[i]; + AString PropName = Prop.get("name", "").asString(); + if (PropName != "textures") + { + continue; + } + m_Textures = Prop.get("value", "").asString(); + m_TexturesSignature = Prop.get("signature", "").asString(); + break; + } // for i - Properties[] +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cMojangAPI: cMojangAPI::cMojangAPI(void) : m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), - m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS) + m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), + m_UUIDToProfileServer(DEFAULT_UUID_TO_PROFILE_SERVER), + m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS) { } @@ -120,8 +176,10 @@ cMojangAPI::~cMojangAPI() void cMojangAPI::Start(cIniFile & a_SettingsIni) { - m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); - m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); + m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER); + m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS); + m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER); + m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS); LoadCachesFromDisk(); } @@ -135,7 +193,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U AString lcPlayerName(a_PlayerName); StrToLower(lcPlayerName); - // Request the cache to populate any names not yet contained: + // Request the cache to query the name if not yet cached: if (!a_UseOnlyCached) { AStringVector PlayerNames; @@ -144,7 +202,8 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U } // Retrieve from cache: - cNameToUUIDMap::const_iterator itr = m_NameToUUID.find(lcPlayerName); + cCSLock Lock(m_CSNameToUUID); + cProfileMap::const_iterator itr = m_NameToUUID.find(lcPlayerName); if (itr == m_NameToUUID.end()) { // No UUID found @@ -157,6 +216,44 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U +AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached) +{ + // Normalize the UUID to lowercase short format that is used as the map key: + AString UUID = StrToLower(MakeUUIDShort(a_UUID)); + + // Retrieve from caches: + { + cCSLock Lock(m_CSUUIDToProfile); + cProfileMap::const_iterator itr = m_UUIDToProfile.find(UUID); + if (itr != m_UUIDToProfile.end()) + { + return itr->second.m_PlayerName; + } + } + { + cCSLock Lock(m_CSUUIDToName); + cProfileMap::const_iterator itr = m_UUIDToName.find(UUID); + if (itr != m_UUIDToName.end()) + { + return itr->second.m_PlayerName; + } + } + + // Name not yet cached, request cache and retry: + if (!a_UseOnlyCached) + { + CacheUUIDToProfile(UUID); + return GetPlayerNameFromUUID(a_UUID, true); + } + + // No value found, none queried. Return an error: + return ""; +} + + + + + AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached) { // Convert all playernames to lowercase: @@ -180,7 +277,7 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx) { - cNameToUUIDMap::const_iterator itrN = m_NameToUUID.find(*itr); + cProfileMap::const_iterator itrN = m_NameToUUID.find(*itr); if (itrN != m_NameToUUID.end()) { res[idx] = itrN->second.m_UUID; @@ -196,10 +293,39 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID) { AString lcName(a_PlayerName); - AString UUID = MakeUUIDShort(a_UUID); + AString UUID = StrToLower(MakeUUIDShort(a_UUID)); Int64 Now = time(NULL); - cCSLock Lock(m_CSNameToUUID); - m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(a_PlayerName, UUID, Now); + { + cCSLock Lock(m_CSNameToUUID); + m_NameToUUID[StrToLower(lcName)] = sProfile(a_PlayerName, UUID, "", "", Now); + } + { + cCSLock Lock(m_CSUUIDToName); + m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now); + } +} + + + + + +void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties) +{ + AString lcName(a_PlayerName); + AString UUID = StrToLower(MakeUUIDShort(a_UUID)); + Int64 Now = time(NULL); + { + cCSLock Lock(m_CSNameToUUID); + m_NameToUUID[StrToLower(lcName)] = sProfile(a_PlayerName, UUID, "", "", Now); + } + { + cCSLock Lock(m_CSUUIDToName); + m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now); + } + { + cCSLock Lock(m_CSUUIDToProfile); + m_UUIDToProfile[UUID] = sProfile(a_PlayerName, UUID, a_Properties, Now); + } } @@ -337,6 +463,7 @@ void cMojangAPI::LoadCachesFromDisk(void) // Open up the SQLite DB: SQLite::Database db("MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); + db.exec("CREATE TABLE IF NOT EXISTS UUIDToProfile (UUID, PlayerName, Textures, TexturesSignature, DateTime)"); // Clean up old entries: { @@ -345,16 +472,40 @@ void cMojangAPI::LoadCachesFromDisk(void) stmt.bind(1, LimitDateTime); stmt.exec(); } + { + SQLite::Statement stmt(db, "DELETE FROM UUIDToProfile WHERE DateTime < ?"); + Int64 LimitDateTime = time(NULL) - MAX_AGE; + stmt.bind(1, LimitDateTime); + stmt.exec(); + } - // Retrieve all remaining entries:: - SQLite::Statement stmt(db, "SELECT PlayerName, UUID, DateTime FROM PlayerNameToUUID"); - while (stmt.executeStep()) + // Retrieve all remaining entries: + { + SQLite::Statement stmt(db, "SELECT PlayerName, UUID, DateTime FROM PlayerNameToUUID"); + while (stmt.executeStep()) + { + AString PlayerName = stmt.getColumn(0); + AString UUID = stmt.getColumn(1); + Int64 DateTime = stmt.getColumn(2); + AString lcPlayerName = PlayerName; + UUID = StrToLower(MakeUUIDShort(UUID)); + m_NameToUUID[StrToLower(lcPlayerName)] = sProfile(PlayerName, UUID, "", "", DateTime); + m_UUIDToName[UUID] = sProfile(PlayerName, UUID, "", "", DateTime); + } + } { - AString PlayerName = stmt.getColumn(0); - AString UUID = stmt.getColumn(1); - Int64 DateTime = stmt.getColumn(2); - AString lcPlayerName = PlayerName; - m_NameToUUID[StrToLower(lcPlayerName)] = sUUIDRecord(PlayerName, UUID, DateTime); + SQLite::Statement stmt(db, "SELECT PlayerName, UUID, Textures, TexturesSignature, DateTime FROM UUIDToProfile"); + while (stmt.executeStep()) + { + AString PlayerName = stmt.getColumn(0); + AString UUID = stmt.getColumn(1); + AString Textures = stmt.getColumn(2); + AString TexturesSignature = stmt.getColumn(2); + Int64 DateTime = stmt.getColumn(4); + AString lcPlayerName = PlayerName; + UUID = StrToLower(MakeUUIDShort(UUID)); + m_UUIDToProfile[StrToLower(lcPlayerName)] = sProfile(PlayerName, UUID, Textures, TexturesSignature, DateTime); + } } } catch (const SQLite::Exception & ex) @@ -374,26 +525,51 @@ void cMojangAPI::SaveCachesToDisk(void) // Open up the SQLite DB: SQLite::Database db("MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); + db.exec("CREATE TABLE IF NOT EXISTS UUIDToProfile (UUID, PlayerName, Textures, TexturesSignature, DateTime)"); // Remove all entries: db.exec("DELETE FROM PlayerNameToUUID"); + db.exec("DELETE FROM UUIDToProfile"); - // Save all cache entries: - SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)"); + // Save all cache entries - m_PlayerNameToUUID: Int64 LimitDateTime = time(NULL) - MAX_AGE; - cCSLock Lock(m_CSNameToUUID); - for (cNameToUUIDMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr) { - if (itr->second.m_DateTime < LimitDateTime) + SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)"); + cCSLock Lock(m_CSNameToUUID); + for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr) { - // This item is too old, do not save - continue; + if (itr->second.m_DateTime < LimitDateTime) + { + // This item is too old, do not save + continue; + } + stmt.bind(1, itr->second.m_PlayerName); + stmt.bind(2, itr->second.m_UUID); + stmt.bind(3, itr->second.m_DateTime); + stmt.exec(); + stmt.reset(); + } + } + + // Save all cache entries - m_UUIDToProfile: + { + SQLite::Statement stmt(db, "INSERT INTO UUIDToProfile(UUID, PlayerName, Textures, TexturesSignature, DateTime) VALUES (?, ?, ?, ?, ?)"); + cCSLock Lock(m_CSUUIDToProfile); + for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr) + { + if (itr->second.m_DateTime < LimitDateTime) + { + // This item is too old, do not save + continue; + } + stmt.bind(1, itr->second.m_UUID); + stmt.bind(2, itr->second.m_PlayerName); + stmt.bind(3, itr->second.m_Textures); + stmt.bind(4, itr->second.m_TexturesSignature); + stmt.bind(5, itr->second.m_DateTime); + stmt.exec(); + stmt.reset(); } - stmt.bind(1, itr->second.m_PlayerName); - stmt.bind(2, itr->second.m_UUID); - stmt.bind(3, itr->second.m_DateTime); - stmt.exec(); - stmt.reset(); } } catch (const SQLite::Exception & ex) @@ -487,22 +663,145 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) // Store the returned results into cache: size_t JsonCount = root.size(); Int64 Now = time(NULL); - cCSLock Lock(m_CSNameToUUID); - for (size_t idx = 0; idx < JsonCount; ++idx) { - Json::Value & Val = root[idx]; - AString JsonName = Val.get("name", "").asString(); - AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); - if (JsonUUID.empty()) + cCSLock Lock(m_CSNameToUUID); + for (size_t idx = 0; idx < JsonCount; ++idx) { - continue; - } - AString lcName = JsonName; - m_NameToUUID[StrToLower(lcName)] = sUUIDRecord(JsonName, JsonUUID, Now); - } // for idx - root[] + Json::Value & Val = root[idx]; + AString JsonName = Val.get("name", "").asString(); + AString JsonUUID = StrToLower(MakeUUIDShort(Val.get("id", "").asString())); + if (JsonUUID.empty()) + { + continue; + } + AString lcName = JsonName; + m_NameToUUID[StrToLower(lcName)] = sProfile(JsonName, JsonUUID, "", "", Now); + } // for idx - root[] + } // cCSLock (m_CSNameToUUID) + + // Also cache the UUIDToName: + { + cCSLock Lock(m_CSUUIDToName); + for (size_t idx = 0; idx < JsonCount; ++idx) + { + Json::Value & Val = root[idx]; + AString JsonName = Val.get("name", "").asString(); + AString JsonUUID = StrToLower(MakeUUIDShort(Val.get("id", "").asString())); + if (JsonUUID.empty()) + { + continue; + } + m_UUIDToName[JsonUUID] = sProfile(JsonName, JsonUUID, "", "", Now); + } // for idx - root[] + } } // while (!NamesToQuery.empty()) } + +void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) +{ + ASSERT(a_UUID.size() == 32); + + // Check if already present: + { + if (m_UUIDToProfile.find(a_UUID) != m_UUIDToProfile.end()) + { + return; + } + } + + // Create the request address: + AString Address = m_UUIDToProfileAddress; + ReplaceString(Address, "%UUID%", a_UUID); + + // Create the HTTP request: + AString Request; + Request += "GET " + Address + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding + Request += "Host: " + m_UUIDToProfileServer + "\r\n"; + Request += "User-Agent: MCServer\r\n"; + Request += "Connection: close\r\n"; + Request += "Content-Length: 0\r\n"; + Request += "\r\n"; + + // Get the response from the server: + AString Response; + if (!SecureRequest(m_UUIDToProfileServer, Request, Response)) + { + return; + } + + // Check the HTTP status line: + const AString Prefix("HTTP/1.1 200 OK"); + AString HexDump; + if (Response.compare(0, Prefix.size(), Prefix)) + { + LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return; + } + + // Erase the HTTP headers from the response: + size_t idxHeadersEnd = Response.find("\r\n\r\n"); + if (idxHeadersEnd == AString::npos) + { + LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); + LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return; + } + Response.erase(0, idxHeadersEnd + 4); + + // Parse the returned string into Json: + Json::Reader reader; + Json::Value root; + if (!reader.parse(Response, root, false) || !root.isObject()) + { + LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); + LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); + return; + } + + /* Example response: + { + "id": "b1caf24202a841a78055a079c460eee7", + "name": "xoft", + "properties": + [ + { + "name": "textures", + "value": "eyJ0aW1lc3RhbXAiOjE0MDcwNzAzMjEyNzEsInByb2ZpbGVJZCI6ImIxY2FmMjQyMDJhODQxYTc4MDU1YTA3OWM0NjBlZWU3IiwicHJvZmlsZU5hbWUiOiJ4b2Z0IiwiaXNQdWJsaWMiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9iNzc5YmFiZjVhNTg3Zjk0OGFkNjc0N2VhOTEyNzU0MjliNjg4Mjk1YWUzYzA3YmQwZTJmNWJmNGQwNTIifX19", + "signature": "XCty+jGEF39hEPrPhYNnCX087kPaoCjYruzYI/DS4nkL5hbjnkSM5Rh15hnUyv/FHhC8OF5rif3D1tQjtMI19KSVaXoUFXpbJM8/+PB8GDgEbX8Fc3u9nYkzOcM/xfxdYsFAdFhLQMkvase/BZLSuPhdy9DdI+TCrO7xuSTZfYmmwVuWo3w5gCY+mSIAnqltnOzaOOTcly75xvO0WYpVk7nJdnR2tvSi0wfrQPDrIg/uzhX7p0SnDqijmBU4QaNez/TNKiFxy69dAzt0RSotlQzqkDbyVKhhv9a4eY8h3pXi4UMftKEj4FAKczxLImkukJXuOn5NN15/Q+le0rJVBC60/xjKIVzltEsMN6qjWD0lQjey7WEL+4pGhCVuWY5KzuZjFvgqszuJTFz7lo+bcHiceldJtea8/fa02eTRObZvdLxbWC9ZfFY0IhpOVKfcLdno/ddDMNMQMi5kMrJ8MZZ/PcW1w5n7MMGWPGCla1kOaC55AL0QYSMGRVEZqgU9wXI5M7sHGZKGM4mWxkbEJYBkpI/p3GyxWgV6v33ZWlsz65TqlNrR1gCLaoFCm7Sif8NqPBZUAONHYon0roXhin/DyEanS93WV6i6FC1Wisscjq2AcvnOlgTo/5nN/1QsMbjNumuMGo37sqjRqlXoPb8zEUbAhhztYuJjEfQ2Rd8=" + } + ] + } + */ + + // Store the returned result into caches: + AString PlayerName = root.get("name", "").asString(); + if (PlayerName.empty()) + { + // No valid playername, bail out + return; + } + Json::Value Properties = root.get("properties", ""); + Int64 Now = time(NULL); + { + cCSLock Lock(m_CSUUIDToProfile); + m_UUIDToProfile[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); + } + { + cCSLock Lock(m_CSUUIDToName); + m_UUIDToName[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); + } + { + AString lcPlayerName(PlayerName); + cCSLock Lock(m_CSNameToUUID); + m_NameToUUID[StrToLower(lcPlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); + } +} + + + + diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 7f3ef4e39..08e799c73 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -11,6 +11,11 @@ #include +namespace Json +{ + class Value; +} + @@ -45,14 +50,24 @@ public: Note: only checks the string's length, not the actual content. */ static AString MakeUUIDDashed(const AString & a_UUID); + // tolua_end + /** Converts a player name into a UUID. The UUID will be empty on error. If a_UseOnlyCached is true, the function only consults the cached values. If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking - operation, do not use this in world-tick thread! */ + operation, do not use this in world-tick thread! + If you have multiple names to resolve, use the GetUUIDsFromPlayerNames() function, it uses a single request for multiple names. */ AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false); - // tolua_end + /** Converts a UUID into a playername. + The returned playername will be empty on error. + Both short and dashed UUID formats are accepted. + Uses both m_UUIDToName and m_UUIDToProfile to search for the value. Uses m_UUIDToProfile for cache. + If a_UseOnlyCached is true, the function only consults the cached values. + If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking + operation, do not use this in world-tick thread! */ + AString GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached = false); /** Converts the player names into UUIDs. a_PlayerName[idx] will be converted to UUID and returned as idx-th value @@ -62,36 +77,61 @@ public: operation, do not use this in world-tick thread! */ AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false); - // tolua_begin - /** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime stamp to now. */ void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID); - // tolua_end - + /** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds + the profile to the respective mapping caches and updtes their datetime stamp to now. */ + void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties); + protected: - struct sUUIDRecord + /** Holds data for a single player profile. */ + struct sProfile { - AString m_PlayerName; // Case-correct playername - AString m_UUID; - Int64 m_DateTime; // UNIXtime of the UUID lookup + AString m_PlayerName; // Case-correct playername + AString m_UUID; // Short lowercased UUID + AString m_Textures; // The Textures field of the profile properties + AString m_TexturesSignature; // The signature of the Textures field of the profile properties + Int64 m_DateTime; // UNIXtime of the profile lookup - sUUIDRecord(void) : + /** Default constructor for the container's sake. */ + sProfile(void) : + m_PlayerName(), m_UUID(), + m_Textures(), + m_TexturesSignature(), m_DateTime(time(NULL)) { } - sUUIDRecord(const AString & a_PlayerName, const AString & a_UUID, Int64 a_DateTime) : + /** Constructor for the storage creation. */ + sProfile( + const AString & a_PlayerName, + const AString & a_UUID, + const AString & a_Textures, + const AString & a_TexturesSignature, + Int64 a_DateTime + ) : m_PlayerName(a_PlayerName), m_UUID(a_UUID), + m_Textures(a_Textures), + m_TexturesSignature(a_TexturesSignature), m_DateTime(a_DateTime) { } + + /** Constructor that parses the values from the Json profile. */ + sProfile( + const AString & a_PlayerName, + const AString & a_UUID, + const Json::Value & a_Properties, + Int64 a_DateTime + ); }; - typedef std::map cNameToUUIDMap; // maps Lowercased PlayerName to sUUIDRecord + typedef std::map cProfileMap; + /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */ AString m_NameToUUIDServer; @@ -100,12 +140,32 @@ protected: For example "/profiles/page/1". */ AString m_NameToUUIDAddress; - /** Cache for the Name-to-UUID lookups. The map key is expected lowercased. Protected by m_CSNameToUUID. */ - cNameToUUIDMap m_NameToUUID; + /** The server to connect to when converting UUID to profile. For example "sessionserver.mojang.com". */ + AString m_UUIDToProfileServer; + + /** The URL to use for converting UUID to profile, without the server part. + Will replace %UUID% with the actual UUID. For example "session/minecraft/profile/%UUID%?unsigned=false". */ + AString m_UUIDToProfileAddress; + + /** Cache for the Name-to-UUID lookups. The map key is lowercased PlayerName. Protected by m_CSNameToUUID. */ + cProfileMap m_NameToUUID; /** Protects m_NameToUUID against simultaneous multi-threaded access. */ cCriticalSection m_CSNameToUUID; + /** Cache for the Name-to-UUID lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToName. */ + cProfileMap m_UUIDToName; + + /** Protects m_UUIDToName against simultaneous multi-threaded access. */ + cCriticalSection m_CSUUIDToName; + + /** Cache for the UUID-to-profile lookups. The map key is lowercased short UUID. + Protected by m_CSUUIDToProfile. */ + cProfileMap m_UUIDToProfile; + + /** Protects m_UUIDToProfile against simultaneous multi-threaded access. */ + cCriticalSection m_CSUUIDToProfile; + /** Loads the caches from a disk storage. */ void LoadCachesFromDisk(void); @@ -113,10 +173,15 @@ protected: /** Saves the caches to a disk storage. */ void SaveCachesToDisk(void); - /** Makes sure all specified names are in the cache. Downloads any missing ones from Mojang API servers. + /** Makes sure all specified names are in the m_PlayerNameToUUID cache. Downloads any missing ones from Mojang API servers. Names that are not valid are not added into the cache. ASSUMEs that a_PlayerNames contains lowercased player names. */ void CacheNamesToUUIDs(const AStringVector & a_PlayerNames); + + /** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers. + UUIDs that are not valid will not be added into the cache. + ASSUMEs that a_UUID is a lowercased short UUID. */ + void CacheUUIDToProfile(const AString & a_UUID); } ; // tolua_export diff --git a/src/Root.h b/src/Root.h index 5cb82edda..1cd175ab4 100644 --- a/src/Root.h +++ b/src/Root.h @@ -88,7 +88,7 @@ public: cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } - cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } // tolua_export + cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread -- cgit v1.2.3 From 3136fc6246a6e0c3ab19eb3dddb1badc7c427ee3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 22:03:48 +0200 Subject: Wolf uses UUID for owner. Fixes #1277. --- src/Mobs/Wolf.cpp | 6 ++- src/Mobs/Wolf.h | 10 ++++- src/WorldStorage/NBTChunkSerializer.cpp | 10 +++-- src/WorldStorage/WSSAnvil.cpp | 69 ++++++++++++++++++++++++++++----- src/WorldStorage/WSSAnvil.h | 4 ++ 5 files changed, 82 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 5bb97d30e..4fe1ff1d6 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -68,6 +68,7 @@ void cWolf::OnRightClicked(cPlayer & a_Player) { if (!IsTame() && !IsAngry()) { + // If the player is holding a bone, try to tame the wolf: if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_BONE) { if (!a_Player.IsGameModeCreative()) @@ -77,14 +78,16 @@ void cWolf::OnRightClicked(cPlayer & a_Player) if (m_World->GetTickRandomNumber(7) == 0) { + // Taming succeeded SetMaxHealth(20); SetIsTame(true); - SetOwner(a_Player.GetName()); + SetOwner(a_Player.GetName(), a_Player.GetUUID()); m_World->BroadcastEntityStatus(*this, esWolfTamed); m_World->BroadcastParticleEffect("heart", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); } else { + // Taming failed m_World->BroadcastEntityStatus(*this, esWolfTaming); m_World->BroadcastParticleEffect("smoke", (float) GetPosX(), (float) GetPosY(), (float) GetPosZ(), 0, 0, 0, 0, 5); } @@ -92,6 +95,7 @@ void cWolf::OnRightClicked(cPlayer & a_Player) } else if (IsTame()) { + // Feed the wolf, restoring its health, or dye its collar: switch (a_Player.GetEquippedItem().m_ItemType) { case E_ITEM_RAW_BEEF: diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index 2e83db701..7500854f8 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -29,7 +29,8 @@ public: bool IsTame (void) const { return m_IsTame; } bool IsBegging (void) const { return m_IsBegging; } bool IsAngry (void) const { return m_IsAngry; } - AString GetOwner (void) const { return m_OwnerName; } + AString GetOwnerName (void) const { return m_OwnerName; } + AString GetOwnerUUID (void) const { return m_OwnerUUID; } int GetCollarColor(void) const { return m_CollarColor; } // Set functions @@ -37,8 +38,12 @@ public: void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; } void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; } void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; } - void SetOwner (const AString & a_NewOwner) { m_OwnerName = a_NewOwner; } void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; } + void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID) + { + m_OwnerName = a_NewOwnerName; + m_OwnerUUID = a_NewOwnerUUID; + } protected: @@ -47,6 +52,7 @@ protected: bool m_IsBegging; bool m_IsAngry; AString m_OwnerName; + AString m_OwnerUUID; int m_CollarColor; } ; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 601cd8833..ecda9b8fd 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -569,10 +569,12 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) } case cMonster::mtWolf: { - m_Writer.AddString("Owner", ((const cWolf *)a_Monster)->GetOwner()); - m_Writer.AddByte("Sitting", (((const cWolf *)a_Monster)->IsSitting() ? 1 : 0)); - m_Writer.AddByte("Angry", (((const cWolf *)a_Monster)->IsAngry() ? 1 : 0)); - m_Writer.AddInt("CollarColor", ((const cWolf *)a_Monster)->GetCollarColor()); + const cWolf & Wolf = *((cWolf *)a_Monster); + m_Writer.AddString("Owner", Wolf.GetOwnerName()); + m_Writer.AddString("OwnerUUID", Wolf.GetOwnerUUID()); + m_Writer.AddByte("Sitting", Wolf.IsSitting() ? 1 : 0); + m_Writer.AddByte("Angry", Wolf.IsAngry() ? 1 : 0); + m_Writer.AddInt("CollarColor", Wolf.GetCollarColor()); break; } case cMonster::mtZombie: diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index d3a156ee1..434f1e21f 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -15,6 +15,7 @@ #include "../ItemGrid.h" #include "../StringCompression.h" #include "../SetChunkData.h" +#include "../Root.h" #include "../BlockEntities/BeaconEntity.h" #include "../BlockEntities/ChestEntity.h" @@ -49,6 +50,8 @@ #include "../Entities/HangingEntity.h" #include "../Entities/ItemFrame.h" +#include "../Protocol/MojangAPI.h" + @@ -2411,16 +2414,9 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N { return; } - int OwnerIdx = a_NBT.FindChildByName(a_TagIdx, "Owner"); - if (OwnerIdx > 0) - { - AString OwnerName = a_NBT.GetString(OwnerIdx); - if (OwnerName != "") - { - Monster->SetOwner(OwnerName); - Monster->SetIsTame(true); - } - } + + LoadWolfOwner(*Monster.get(), a_NBT, a_TagIdx); + int SittingIdx = a_NBT.FindChildByName(a_TagIdx, "Sitting"); if (SittingIdx > 0) { @@ -2492,6 +2488,59 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT +void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_TagIdx) +{ + // Load the owner information. OwnerUUID or Owner may be specified, possibly both: + AString OwnerUUID, OwnerName; + int OwnerUUIDIdx = a_NBT.FindChildByName(a_TagIdx, "OwnerUUID"); + if (OwnerUUIDIdx > 0) + { + OwnerUUID = cMojangAPI::MakeUUIDShort(a_NBT.GetString(OwnerUUIDIdx)); + } + int OwnerIdx = a_NBT.FindChildByName(a_TagIdx, "Owner"); + if (OwnerIdx > 0) + { + OwnerName = a_NBT.GetString(OwnerIdx); + } + if (OwnerName.empty() && OwnerUUID.empty()) + { + // There is no owner, bail out: + return; + } + + // Convert name to UUID, if needed: + if (OwnerUUID.empty()) + { + // This wolf has only playername stored (pre-1.7.6), look up the UUID + // The lookup is blocking, but we're running in a separate thread, so it's ok + OwnerUUID = cRoot::Get()->GetMojangAPI().GetUUIDFromPlayerName(OwnerName); + if (OwnerUUID.empty()) + { + // Not a known player, un-tame the wolf by bailing out + return; + } + } + + // Convert UUID to name, if needed: + if (OwnerName.empty()) + { + // The lookup is blocking, but we're running in a separate thread, so it's ok + OwnerName = cRoot::Get()->GetMojangAPI().GetPlayerNameFromUUID(OwnerUUID); + if (OwnerName.empty()) + { + // Not a known player, un-tame the wolf by bailing out + return; + } + } + + a_Wolf.SetOwner(OwnerName, OwnerUUID); + a_Wolf.SetIsTame(true); +} + + + + + bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { double Pos[3]; diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index f8eeb8247..a41268f4c 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -21,6 +21,7 @@ class cItemGrid; class cProjectileEntity; class cHangingEntity; +class cWolf; @@ -201,6 +202,9 @@ protected: void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + /** Loads the wolf's owner information from the NBT into the specified wolf entity. */ + void LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_TagIdx); + /// Loads entity common data from the NBT compound; returns true if successful bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From 977a9948b9ed52d0dd8c4695ecfca981b06bb212 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 3 Aug 2014 22:15:26 +0200 Subject: Fixed skins in mc 1.7.9/1.7.10 --- src/Protocol/Protocol17x.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f419c01a7..d6f4b96dc 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -3032,15 +3032,14 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); Pkt.WriteString(a_Player.GetName()); - const Json::Value & Properties = m_Client->GetProperties(); - const Json::Value::const_iterator End = Properties.end(); + const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); Pkt.WriteVarInt(Properties.size()); - for (Json::Value::iterator itr = Properties.begin(); itr != End; ++itr) + for (Json::Value::iterator itr = Properties.begin(); itr != Properties.end(); ++itr) { - Pkt.WriteString(((Json::Value)*itr).get("name", "").toStyledString()); - Pkt.WriteString(((Json::Value)*itr).get("value", "").toStyledString()); - Pkt.WriteString(((Json::Value)*itr).get("signature", "").toStyledString()); + Pkt.WriteString(((Json::Value)*itr).get("name", "").asString()); + Pkt.WriteString(((Json::Value)*itr).get("value", "").asString()); + Pkt.WriteString(((Json::Value)*itr).get("signature", "").asString()); } Pkt.WriteFPInt(a_Player.GetPosX()); -- cgit v1.2.3 From b19874e6f2c8894648c25efb0e9fa176b6688729 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 3 Aug 2014 22:19:43 +0200 Subject: Attempting a compilation fix for gcc / clang. --- src/StringUtils.cpp | 15 +++++++++++++++ src/StringUtils.h | 3 +++ 2 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index b0e5a4ffe..decce8065 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -230,6 +230,21 @@ AString & StrToLower(AString & s) +AString StrToLower(const AString & s) +{ + AString res; + res.resize(s.size()); + for (AString::iterator itr = res.begin(), end = res.end(); itr != end; ++itr) + { + *itr = (char)tolower(*itr); + } + return res; +} + + + + + int NoCaseCompare(const AString & s1, const AString & s2) { #ifdef _MSC_VER diff --git a/src/StringUtils.h b/src/StringUtils.h index 30b9904d1..65363382d 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -48,6 +48,9 @@ extern AString & StrToUpper(AString & s); /// In-place string conversion to lowercase; returns the same string extern AString & StrToLower(AString & s); +/** Returns a lower-cased copy of the string */ +extern AString StrToLower(const AString & s); + /// Case-insensitive string comparison; returns 0 if the strings are the same extern int NoCaseCompare(const AString & s1, const AString & s2); // tolua_export -- cgit v1.2.3 From 0911072d27820bd608bb908088419d3ec5151434 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 01:34:12 +0200 Subject: Attempt to fix knockback and swimming. --- src/Entities/Entity.cpp | 28 +++++++++++++--------------- src/Mobs/Monster.cpp | 12 +++++++++--- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index a274e6780..32f220897 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -244,9 +244,9 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R Vector3d Heading(0, 0, 0); if (a_Attacker != NULL) { - Heading = a_Attacker->GetLookVector() * (a_Attacker->IsSprinting() ? 10 : 8); + Heading = a_Attacker->GetLookVector() * (a_Attacker->IsSprinting() ? 16 : 11); + Heading.y = 1.6; } - Heading.y = 2; TDI.Knockback = Heading * a_KnockbackAmount; DoTakeDamage(TDI); @@ -731,21 +731,19 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) } NextSpeed.y += fallspeed; } - else + + // Friction + if (NextSpeed.SqrLength() > 0.0004f) { - // Friction - if (NextSpeed.SqrLength() > 0.0004f) + NextSpeed.x *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.x) < 0.05) { - NextSpeed.x *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.x) < 0.05) - { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) - { - NextSpeed.z = 0; - } + NextSpeed.x = 0; + } + NextSpeed.z *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.z) < 0.05) + { + NextSpeed.z = 0; } } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 94df991a3..66c9aadeb 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -292,6 +292,10 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) { Distance *= 2.5; } + else if (IsSwimming()) + { + Distance *= 1.3; + } else { // Don't let the mob move too much if he's falling. @@ -301,11 +305,13 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) AddSpeedX(Distance.x); AddSpeedZ(Distance.z); - if (m_EMState == ESCAPING) - { // Runs Faster when escaping :D otherwise they just walk away + /* It's too buggy! */ + /** if (m_EMState == ESCAPING) + { + // Runs Faster when escaping :D otherwise they just walk away SetSpeedX (GetSpeedX() * 2.f); SetSpeedZ (GetSpeedZ() * 2.f); - } + } */ } else { -- cgit v1.2.3 From 7bea90d6caca9f9b4389fe14ab49720f22cb9273 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 01:35:25 +0200 Subject: Fixed warnings --- src/Mobs/Monster.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 66c9aadeb..54ad869c2 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -290,16 +290,16 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) if (m_bOnGround) { - Distance *= 2.5; + Distance *= 2.5f; } else if (IsSwimming()) { - Distance *= 1.3; + Distance *= 1.3f; } else { // Don't let the mob move too much if he's falling. - Distance *= 0.25; + Distance *= 0.25f; } AddSpeedX(Distance.x); -- cgit v1.2.3 From 122344bb7a71b7b4797869083c4c61f08882927a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 08:00:49 +0200 Subject: Rewritten string case manipulation to use std::transform. --- src/StringUtils.cpp | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index decce8065..0e30e8ebb 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -198,14 +198,7 @@ AString TrimString(const AString & str) AString & StrToUpper(AString & s) { - AString::iterator i = s.begin(); - AString::iterator end = s.end(); - - while (i != end) - { - *i = (char)toupper(*i); - ++i; - } + std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s; } @@ -215,14 +208,7 @@ AString & StrToUpper(AString & s) AString & StrToLower(AString & s) { - AString::iterator i = s.begin(); - AString::iterator end = s.end(); - - while (i != end) - { - *i = (char)tolower(*i); - ++i; - } + std::transform(s.begin(), s.end(), s.begin(), ::tolower); return s; } @@ -232,12 +218,8 @@ AString & StrToLower(AString & s) AString StrToLower(const AString & s) { - AString res; - res.resize(s.size()); - for (AString::iterator itr = res.begin(), end = res.end(); itr != end; ++itr) - { - *itr = (char)tolower(*itr); - } + AString res(s); + std::transform(res.begin(), res.end(), res.begin(), ::tolower); return res; } -- cgit v1.2.3 From e70077361d239f3f3a9d8a94c8262d663018f901 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 11:23:35 +0200 Subject: Changed /** to /* --- src/Mobs/Monster.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 54ad869c2..a9889b62f 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -305,13 +305,15 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) AddSpeedX(Distance.x); AddSpeedZ(Distance.z); - /* It's too buggy! */ - /** if (m_EMState == ESCAPING) + // It's too buggy! + /* + if (m_EMState == ESCAPING) { // Runs Faster when escaping :D otherwise they just walk away SetSpeedX (GetSpeedX() * 2.f); SetSpeedZ (GetSpeedZ() * 2.f); - } */ + } + */ } else { -- cgit v1.2.3 From 8cdcfcceb38c057015d5822fa2ec06acf767f81d Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 11:26:31 +0200 Subject: Changed properties for-loop. --- src/Protocol/Protocol17x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index d6f4b96dc..8f3399b2f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -3035,7 +3035,7 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); Pkt.WriteVarInt(Properties.size()); - for (Json::Value::iterator itr = Properties.begin(); itr != Properties.end(); ++itr) + for (Json::Value::iterator itr = Properties.begin(), end = Properties.end(); itr != end; ++itr) { Pkt.WriteString(((Json::Value)*itr).get("name", "").asString()); Pkt.WriteString(((Json::Value)*itr).get("value", "").asString()); -- cgit v1.2.3 From 054ce9bcc45018b9f024654e7d35327fbc20d119 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 11:29:40 +0200 Subject: Anvil: Wolf owner not saved if not present. --- src/WorldStorage/NBTChunkSerializer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index ecda9b8fd..e435a1b1f 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -570,8 +570,14 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) case cMonster::mtWolf: { const cWolf & Wolf = *((cWolf *)a_Monster); - m_Writer.AddString("Owner", Wolf.GetOwnerName()); - m_Writer.AddString("OwnerUUID", Wolf.GetOwnerUUID()); + if (!Wolf.GetOwnerName().empty()) + { + m_Writer.AddString("Owner", Wolf.GetOwnerName()); + } + if (!Wolf.GetOwnerUUID().empty()) + { + m_Writer.AddString("OwnerUUID", Wolf.GetOwnerUUID()); + } m_Writer.AddByte("Sitting", Wolf.IsSitting() ? 1 : 0); m_Writer.AddByte("Angry", Wolf.IsAngry() ? 1 : 0); m_Writer.AddInt("CollarColor", Wolf.GetCollarColor()); -- cgit v1.2.3 From 1fa210c7f91030ac18fd880fcf131e8104c0b889 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 11:16:19 +0200 Subject: Refactored case-conversion functions. StrToLower() returns a modified copy of the string, InPlaceLowercase() modifies the string in-place. --- src/HTTPServer/HTTPMessage.cpp | 3 +-- src/Mobs/Monster.cpp | 3 +-- src/Protocol/MojangAPI.cpp | 52 ++++++++++++++++++------------------------ src/Protocol/MojangAPI.h | 4 ++-- src/StringUtils.cpp | 25 +++++++++++++------- src/StringUtils.h | 7 ++++-- src/WorldStorage/WSSAnvil.cpp | 7 +++++- 7 files changed, 54 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp index 4226352e9..65d73fd87 100644 --- a/src/HTTPServer/HTTPMessage.cpp +++ b/src/HTTPServer/HTTPMessage.cpp @@ -35,8 +35,7 @@ cHTTPMessage::cHTTPMessage(eKind a_Kind) : void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value) { - AString Key = a_Key; - StrToLower(Key); + AString Key = StrToLower(a_Key); cNameValueMap::iterator itr = m_Headers.find(Key); if (itr == m_Headers.end()) { diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 94df991a3..53334753a 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -710,8 +710,7 @@ AString cMonster::MobTypeToString(cMonster::eType a_MobType) cMonster::eType cMonster::StringToMobType(const AString & a_Name) { - AString lcName(a_Name); - StrToLower(lcName); + AString lcName = StrToLower(a_Name); // Binary-search for the lowercase name: int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames) - 1; diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 9fdf07380..a7aea5490 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -190,8 +190,7 @@ void cMojangAPI::Start(cIniFile & a_SettingsIni) AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached) { // Convert the playername to lowercase: - AString lcPlayerName(a_PlayerName); - StrToLower(lcPlayerName); + AString lcPlayerName = StrToLower(a_PlayerName); // Request the cache to query the name if not yet cached: if (!a_UseOnlyCached) @@ -219,7 +218,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached) { // Normalize the UUID to lowercase short format that is used as the map key: - AString UUID = StrToLower(MakeUUIDShort(a_UUID)); + AString UUID = MakeUUIDShort(a_UUID); // Retrieve from caches: { @@ -260,8 +259,7 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player AStringVector PlayerNames; for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { - AString Lower(*itr); - PlayerNames.push_back(StrToLower(Lower)); + PlayerNames.push_back(StrToLower(*itr)); } // for itr - a_PlayerNames[] // Request the cache to populate any names not yet contained: @@ -292,12 +290,11 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID) { - AString lcName(a_PlayerName); - AString UUID = StrToLower(MakeUUIDShort(a_UUID)); + AString UUID = MakeUUIDShort(a_UUID); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); - m_NameToUUID[StrToLower(lcName)] = sProfile(a_PlayerName, UUID, "", "", Now); + m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now); } { cCSLock Lock(m_CSUUIDToName); @@ -311,12 +308,11 @@ void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties) { - AString lcName(a_PlayerName); - AString UUID = StrToLower(MakeUUIDShort(a_UUID)); + AString UUID = MakeUUIDShort(a_UUID); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); - m_NameToUUID[StrToLower(lcName)] = sProfile(a_PlayerName, UUID, "", "", Now); + m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now); } { cCSLock Lock(m_CSUUIDToName); @@ -395,13 +391,13 @@ AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) { case 32: { - // Already is a short UUID - return a_UUID; + // Already is a short UUID, only lowercase + return StrToLower(a_UUID); } case 36: { - // Remove the dashes from the string: + // Remove the dashes from the string by appending together the parts between them: AString res; res.reserve(32); res.append(a_UUID, 0, 8); @@ -409,7 +405,7 @@ AString cMojangAPI::MakeUUIDShort(const AString & a_UUID) res.append(a_UUID, 14, 4); res.append(a_UUID, 19, 4); res.append(a_UUID, 24, 12); - return res; + return StrToLower(res); } } LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str()); @@ -427,8 +423,8 @@ AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) { case 36: { - // Already is a dashed UUID - return a_UUID; + // Already is a dashed UUID, only lowercase + return StrToLower(a_UUID); } case 32: @@ -445,7 +441,7 @@ AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID) res.append(a_UUID, 16, 4); res.push_back('-'); res.append(a_UUID, 20, 12); - return res; + return StrToLower(res); } } LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str()); @@ -487,9 +483,8 @@ void cMojangAPI::LoadCachesFromDisk(void) AString PlayerName = stmt.getColumn(0); AString UUID = stmt.getColumn(1); Int64 DateTime = stmt.getColumn(2); - AString lcPlayerName = PlayerName; - UUID = StrToLower(MakeUUIDShort(UUID)); - m_NameToUUID[StrToLower(lcPlayerName)] = sProfile(PlayerName, UUID, "", "", DateTime); + UUID = MakeUUIDShort(UUID); + m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, UUID, "", "", DateTime); m_UUIDToName[UUID] = sProfile(PlayerName, UUID, "", "", DateTime); } } @@ -502,9 +497,8 @@ void cMojangAPI::LoadCachesFromDisk(void) AString Textures = stmt.getColumn(2); AString TexturesSignature = stmt.getColumn(2); Int64 DateTime = stmt.getColumn(4); - AString lcPlayerName = PlayerName; - UUID = StrToLower(MakeUUIDShort(UUID)); - m_UUIDToProfile[StrToLower(lcPlayerName)] = sProfile(PlayerName, UUID, Textures, TexturesSignature, DateTime); + UUID = MakeUUIDShort(UUID); + m_UUIDToProfile[UUID] = sProfile(PlayerName, UUID, Textures, TexturesSignature, DateTime); } } } @@ -669,13 +663,12 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); - AString JsonUUID = StrToLower(MakeUUIDShort(Val.get("id", "").asString())); + AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } - AString lcName = JsonName; - m_NameToUUID[StrToLower(lcName)] = sProfile(JsonName, JsonUUID, "", "", Now); + m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } // cCSLock (m_CSNameToUUID) @@ -686,7 +679,7 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); - AString JsonUUID = StrToLower(MakeUUIDShort(Val.get("id", "").asString())); + AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; @@ -796,9 +789,8 @@ void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) m_UUIDToName[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); } { - AString lcPlayerName(PlayerName); cCSLock Lock(m_CSNameToUUID); - m_NameToUUID[StrToLower(lcPlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); + m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); } } diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 08e799c73..6ed37625e 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -40,12 +40,12 @@ public: // tolua_begin - /** Converts the given UUID to its short form (32 bytes, no dashes). + /** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase). Logs a warning and returns empty string if not a UUID. Note: only checks the string's length, not the actual content. */ static AString MakeUUIDShort(const AString & a_UUID); - /** Converts the given UUID to its dashed form (36 bytes, 4 dashes). + /** Normalizes the given UUID to its dashed form (36 bytes, 4 dashes, lowercase). Logs a warning and returns empty string if not a UUID. Note: only checks the string's length, not the actual content. */ static AString MakeUUIDDashed(const AString & a_UUID); diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 0e30e8ebb..5f88cbf64 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -196,9 +196,9 @@ AString TrimString(const AString & str) -AString & StrToUpper(AString & s) +AString & InPlaceLowercase(AString & s) { - std::transform(s.begin(), s.end(), s.begin(), ::toupper); + std::transform(s.begin(), s.end(), s.begin(), ::tolower); return s; } @@ -206,9 +206,9 @@ AString & StrToUpper(AString & s) -AString & StrToLower(AString & s) +AString & InPlaceUppercase(AString & s) { - std::transform(s.begin(), s.end(), s.begin(), ::tolower); + std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s; } @@ -227,16 +227,25 @@ AString StrToLower(const AString & s) +AString StrToUpper(const AString & s) +{ + AString res(s); + std::transform(res.begin(), res.end(), res.begin(), ::toupper); + return res; +} + + + + + int NoCaseCompare(const AString & s1, const AString & s2) { #ifdef _MSC_VER // MSVC has stricmp that compares case-insensitive: return _stricmp(s1.c_str(), s2.c_str()); #else - // Do it the hard way: - AString s1Copy(s1); - AString s2Copy(s2); - return StrToUpper(s1Copy).compare(StrToUpper(s2Copy)); + // Do it the hard way - convert both strings to lowercase: + return StrToLower(s1).compare(StrToLower(s2)); #endif // else _MSC_VER } diff --git a/src/StringUtils.h b/src/StringUtils.h index 65363382d..142aaf59b 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -43,10 +43,13 @@ extern AStringVector StringSplitAndTrim(const AString & str, const AString & del extern AString TrimString(const AString & str); // tolua_export /// In-place string conversion to uppercase; returns the same string -extern AString & StrToUpper(AString & s); +extern AString & InPlaceUppercase(AString & s); /// In-place string conversion to lowercase; returns the same string -extern AString & StrToLower(AString & s); +extern AString & InPlaceLowercase(AString & s); + +/** Returns an upper-cased copy of the string */ +extern AString StrToUpper(const AString & s); /** Returns a lower-cased copy of the string */ extern AString StrToLower(const AString & s); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 434f1e21f..a9c9ae4b5 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2495,7 +2495,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta int OwnerUUIDIdx = a_NBT.FindChildByName(a_TagIdx, "OwnerUUID"); if (OwnerUUIDIdx > 0) { - OwnerUUID = cMojangAPI::MakeUUIDShort(a_NBT.GetString(OwnerUUIDIdx)); + OwnerUUID = a_NBT.GetString(OwnerUUIDIdx); } int OwnerIdx = a_NBT.FindChildByName(a_TagIdx, "Owner"); if (OwnerIdx > 0) @@ -2520,6 +2520,11 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta return; } } + else + { + // Normalize the UUID: + OwnerUUID = cMojangAPI::MakeUUIDShort(OwnerUUID); + } // Convert UUID to name, if needed: if (OwnerName.empty()) -- cgit v1.2.3 From ff37192e945c9083d313ddc8924ef433e193f9c7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 12:03:37 +0200 Subject: BasicStyleCheck: Dividers are exactly 80 slashes. --- src/CheckBasicStyle.lua | 18 +++++++++++++++++- src/Mobs/Enderman.cpp | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index 13a6d15d2..c743a84a5 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -10,11 +10,12 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Spaces after comma, not before - Opening braces not at the end of a code line - Spaces after if, for, while + - Line dividers (////...) exactly 80 slashes - (TODO) Spaces before *, /, & - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase - - (TODO) Line dividers (////...) exactly 80 slashes - (TODO) Not using "* "-style doxy comment continuation lines + - (TODO) Multi-level indent change Violations that cannot be checked easily: - Spaces around "+" (there are things like "a++", "++a", "a += 1", "X+", "stack +1" and ascii-drawn tables) @@ -165,6 +166,21 @@ local function ProcessFile(a_FileName) for _, pat in ipairs(g_ViolationPatterns) do ReportViolationIfFound(a_Line, a_FileName, lineCounter, pat[1], pat[2]) end + + local dividerStart, dividerEnd = a_Line:find("/////*") + if (dividerStart) then + if (dividerEnd ~= dividerStart + 79) then + ReportViolation(a_FileName, lineCounter, 1, 80, "Divider comment should have exactly 80 slashes") + end + if (dividerStart > 1) then + if ( + (a_Line:sub(1, dividerStart - 1) ~= string.rep("\t", dividerStart - 1)) or -- The divider should have only indent in front of it + (a_Line:len() > dividerEnd + 1) -- The divider should have no other text following it + ) then + ReportViolation(a_FileName, lineCounter, 1, 80, "Divider comment shouldn't have any extra text around it") + end + end + end lineCounter = lineCounter + 1 end diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 0a1b6491a..51255beb3 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -8,7 +8,7 @@ -/////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cPlayerLookCheck class cPlayerLookCheck : public cPlayerListCallback -- cgit v1.2.3 From 7bfb0b05d0514c47095ba3ec8ebb6a1073d9962a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 13:20:16 +0200 Subject: CheckBasicStyle: multi-level indent change. --- src/Bindings/WebPlugin.cpp | 2 ++ src/CheckBasicStyle.lua | 17 ++++++++++++++++- src/Entities/HangingEntity.cpp | 2 +- src/Generating/Noise3DGenerator.cpp | 5 +++-- src/Generating/StructGen.cpp | 6 +++--- src/Simulator/IncrementalRedstoneSimulator.cpp | 6 +++--- src/WorldStorage/WorldStorage.h | 8 +++++--- 7 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index 1178c127a..4fa64d937 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -81,7 +81,9 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest else // Otherwise show the first tab { if (GetTabs().size() > 0) + { Tab = *GetTabs().begin(); + } } if (Tab != NULL) diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index c743a84a5..bf81a7cd5 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -11,11 +11,11 @@ Checks that all source files (*.cpp, *.h) use the basic style requirements of th - Opening braces not at the end of a code line - Spaces after if, for, while - Line dividers (////...) exactly 80 slashes + - Multi-level indent change - (TODO) Spaces before *, /, & - (TODO) Hex numbers with even digit length - (TODO) Hex numbers in lowercase - (TODO) Not using "* "-style doxy comment continuation lines - - (TODO) Multi-level indent change Violations that cannot be checked easily: - Spaces around "+" (there are things like "a++", "++a", "a += 1", "X+", "stack +1" and ascii-drawn tables) @@ -159,6 +159,7 @@ local function ProcessFile(a_FileName) -- Process each line separately: -- Ref.: http://stackoverflow.com/questions/10416869/iterate-over-possibly-empty-lines-in-a-way-that-matches-the-expectations-of-exis local lineCounter = 1 + local lastIndentLevel = 0 all:gsub("\r\n", "\n") -- normalize CRLF into LF-only string.gsub(all .. "\n", "[^\n]*\n", -- Iterate over each line, while preserving empty lines function(a_Line) @@ -167,6 +168,7 @@ local function ProcessFile(a_FileName) ReportViolationIfFound(a_Line, a_FileName, lineCounter, pat[1], pat[2]) end + -- Check that divider comments are well formed - 80 slashes plus optional indent: local dividerStart, dividerEnd = a_Line:find("/////*") if (dividerStart) then if (dividerEnd ~= dividerStart + 79) then @@ -181,6 +183,19 @@ local function ProcessFile(a_FileName) end end end + + -- Check the indent level change from the last line, if it's too much, report: + local indentStart, indentEnd = a_Line:find("\t+") + local indentLevel = 0 + if (indentStart) then + indentLevel = indentEnd - indentStart + end + if (indentLevel > 0) then + if ((lastIndentLevel - indentLevel >= 2) or (lastIndentLevel - indentLevel <= -2)) then + ReportViolation(a_FileName, lineCounter, 1, indentStart or 1, "Indent changed more than a single level between the previous line and this one: from " .. lastIndentLevel .. " to " .. indentLevel) + end + lastIndentLevel = indentLevel + end lineCounter = lineCounter + 1 end diff --git a/src/Entities/HangingEntity.cpp b/src/Entities/HangingEntity.cpp index 32d2b226d..8c70c606e 100644 --- a/src/Entities/HangingEntity.cpp +++ b/src/Entities/HangingEntity.cpp @@ -24,7 +24,7 @@ cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle) { int Dir = 0; - + // The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces switch (m_BlockFace) { diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index b879349ee..eb816f564 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -412,11 +412,12 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) for (int x = 0; x < 17; x += UPSCALE_X) { NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + x)) / m_FrequencyX; - CurFloor[x + 17 * z] = + CurFloor[x + 17 * z] = ( m_Noise1.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * (NOISE_DATATYPE)0.5 + m_Noise2.CubicNoise3D(NoiseX / 2, NoiseY / 2, NoiseZ / 2) + m_Noise3.CubicNoise3D(NoiseX / 4, NoiseY / 4, NoiseZ / 4) * 2 + - AddHeight / Height[x + 17 * z]; + AddHeight / Height[x + 17 * z] + ); } } // Linear-interpolate this XZ floor: diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 054eec345..f7e609353 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -585,10 +585,10 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) // First update the high floor: for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) { - FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = + FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = ( m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) * - m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / - 256; + m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256 + ); } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index ada8de4b8..c1a2fcaae 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -847,7 +847,7 @@ void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_Rel bool m_IsPowered; public: cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - + virtual bool Item(cDropSpenserEntity * a_DropSpenser) override { a_DropSpenser->SetRedstonePower(m_IsPowered); @@ -948,7 +948,7 @@ void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_RelBlockX, int a_Re bool m_IsPowered; public: cSetPowerToCommandBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - + virtual bool Item(cCommandBlockEntity * a_CommandBlock) override { a_CommandBlock->SetRedstonePower(m_IsPowered); @@ -1844,7 +1844,7 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_RelBlockX, i { return; } - + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index 5d8aa4589..dd07ecb64 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -95,9 +95,11 @@ protected: bool operator ==(const sChunkLoad other) const { - return this->m_ChunkX == other.m_ChunkX && - this->m_ChunkY == other.m_ChunkY && - this->m_ChunkZ == other.m_ChunkZ; + return ( + (this->m_ChunkX == other.m_ChunkX) && + (this->m_ChunkY == other.m_ChunkY) && + (this->m_ChunkZ == other.m_ChunkZ) + ); } } ; -- cgit v1.2.3 From f5b71cc1f86c383891d2c0da7a3be5355ee1816e Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 20:16:52 +0200 Subject: Fixed #1286 --- src/Protocol/Protocol17x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 8f3399b2f..318342f09 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -820,7 +820,7 @@ void cProtocol172::SendPlayerAbilities(void) } Pkt.WriteByte(Flags); Pkt.WriteFloat((float)(0.05 * Player->GetFlyingMaxSpeed())); - Pkt.WriteFloat((float)(0.1 * Player->GetMaxSpeed())); + Pkt.WriteFloat((float)(0.1 * Player->GetNormalMaxSpeed())); } -- cgit v1.2.3 From 434ea542e174bc686a7c981476e23d30d18989c3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 21:48:33 +0200 Subject: Added arrow consuming on shooting --- src/Items/ItemBow.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index e7a77dcbc..90645dd9a 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -57,6 +57,12 @@ public: } Force = std::min(Force, 1.0); + // Has the player a arrow? + if (!a_Player->IsGameModeCreative() && !a_Player->GetInventory().HasItems(cItem(E_ITEM_ARROW))) + { + return; + } + // Create the arrow entity: cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2); if (Arrow == NULL) @@ -73,6 +79,10 @@ public: a_Player->GetWorld()->BroadcastSoundEffect("random.bow", a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), 0.5, (float)Force); if (!a_Player->IsGameModeCreative()) { + if (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchInfinity) == 0) + { + a_Player->GetInventory().RemoveItem(cItem(E_ITEM_ARROW)); + } a_Player->UseEquippedItem(); } } -- cgit v1.2.3 From de9d908792c7dfbc13db87a3508a8c4b0516d01c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 4 Aug 2014 21:21:35 +0100 Subject: Made AllToLua output consistent --- src/Bindings/gen_LuaState_Call.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index fb1797dc0..17bae82b3 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -13,7 +13,7 @@ separate the arguments from the return values, a special type of cLuaState::cRet -print("Generating LuaState_Call.inc...") +print("Generating LuaState_Call.inc . . .") @@ -189,7 +189,7 @@ f:close() -print("LuaState_Call.inc generated") +print("LuaState_Call.inc generated.") -- cgit v1.2.3 From 0b9eb20b92f49feeb34626eef4590f7938a93480 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 4 Aug 2014 21:22:08 +0100 Subject: Fixed signs not staying on other signs --- src/Blocks/BlockSignPost.h | 3 ++- src/Blocks/BlockWallSign.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h index ee65d099a..d0cc760b0 100644 --- a/src/Blocks/BlockSignPost.h +++ b/src/Blocks/BlockSignPost.h @@ -39,8 +39,9 @@ public: { return false; } + BLOCKTYPE Type = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); - return (cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); + return ((Type == E_BLOCK_SIGN_POST) || cBlockInfo::IsSolid(Type)); } diff --git a/src/Blocks/BlockWallSign.h b/src/Blocks/BlockWallSign.h index e837b315e..47649379e 100644 --- a/src/Blocks/BlockWallSign.h +++ b/src/Blocks/BlockWallSign.h @@ -49,8 +49,9 @@ public: int BlockX = (a_Chunk.GetPosX() * cChunkDef::Width) + a_RelX; int BlockZ = (a_Chunk.GetPosZ() * cChunkDef::Width) + a_RelZ; GetBlockCoordsBehindTheSign(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ), BlockX, BlockZ); + BLOCKTYPE Type = a_ChunkInterface.GetBlock(BlockX, a_RelY, BlockZ); - return (cBlockInfo::IsSolid(a_ChunkInterface.GetBlock(BlockX, a_RelY, BlockZ))); + return ((Type == E_BLOCK_WALLSIGN) || (Type == E_BLOCK_SIGN_POST) || cBlockInfo::IsSolid(Type)); } -- cgit v1.2.3 From 2e43eaaba7a29a9db5bfa11d6a1bb8b57bf02fa6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 4 Aug 2014 22:30:13 +0200 Subject: Changed arrow comment. --- src/Items/ItemBow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index 90645dd9a..fdc24689c 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -57,7 +57,7 @@ public: } Force = std::min(Force, 1.0); - // Has the player a arrow? + // Does the player have an arrow? if (!a_Player->IsGameModeCreative() && !a_Player->GetInventory().HasItems(cItem(E_ITEM_ARROW))) { return; -- cgit v1.2.3 From 9113b45673bc9b0202ce821b8db2dbe6f4b425b9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 4 Aug 2014 23:35:32 +0200 Subject: MojangAPI: Fixed PlayerNameToUUID(). --- src/Protocol/MojangAPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index a7aea5490..823ff5469 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -208,7 +208,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U // No UUID found return ""; } - return itr->second.m_PlayerName; + return itr->second.m_UUID; } -- cgit v1.2.3 From d2d0ffee21d10aace8caa20a002daa1c887c1f39 Mon Sep 17 00:00:00 2001 From: archshift Date: Mon, 4 Aug 2014 19:43:33 -0700 Subject: Fixed unsigned long comparison to size_t --- src/Items/ItemHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 1c1e3b5b9..bceedaf69 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -66,7 +66,7 @@ cItemHandler * cItemHandler::m_ItemHandler[2268]; cItemHandler * cItemHandler::GetItemHandler(int a_ItemType) { - if ((a_ItemType < 0) || ((unsigned long)a_ItemType >= ARRAYCOUNT(m_ItemHandler))) + if ((a_ItemType < 0) || ((size_t)a_ItemType >= ARRAYCOUNT(m_ItemHandler))) { // Either nothing (-1), or bad value, both cases should return the air handler if (a_ItemType < -1) -- cgit v1.2.3 From a92cff20ea59b68827a6f579d0ba9ccb40276d6b Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 5 Aug 2014 13:47:10 +0200 Subject: Added Clamp() function to the lua api. --- src/Bindings/ManualBindings.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 042ffb19e..b41cd94bc 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -82,6 +82,33 @@ static int lua_do_error(lua_State* L, const char * a_pFormat, ...) // Lua bound functions with special return types +static int tolua_Clamp(lua_State * tolua_S) +{ + cLuaState LuaState(tolua_S); + int NumArgs = lua_gettop(LuaState); + if (NumArgs != 3) + { + return lua_do_error(LuaState, "Error in function call '#funcname#': Requires 3 arguments, got %i", NumArgs); + } + + if (!lua_isnumber(LuaState, 1) || !lua_isnumber(LuaState, 2) || !lua_isnumber(LuaState, 3)) + { + return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); + } + + int Min = (int)tolua_tonumber(LuaState, 1, 0); + int Number = (int)tolua_tonumber(LuaState, 2, 0); + int Max = (int)tolua_tonumber(LuaState, 3, 0); + + int Result = std::min(std::max(Min, Number), Max); + LuaState.Push(Result); + return 1; +} + + + + + static int tolua_StringSplit(lua_State * tolua_S) { cLuaState LuaState(tolua_S); @@ -3103,6 +3130,7 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) void ManualBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); + tolua_function(tolua_S, "Clamp", tolua_Clamp); tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); tolua_function(tolua_S, "LOG", tolua_LOG); -- cgit v1.2.3 From 43de9af8786243c90832b78f8c19ec92fb218392 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 5 Aug 2014 13:54:04 +0200 Subject: Added api documentation for Clamp() --- src/Bindings/ManualBindings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index b41cd94bc..81065a7e1 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -96,8 +96,8 @@ static int tolua_Clamp(lua_State * tolua_S) return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); } - int Min = (int)tolua_tonumber(LuaState, 1, 0); - int Number = (int)tolua_tonumber(LuaState, 2, 0); + int Number = (int)tolua_tonumber(LuaState, 1, 0); + int Min = (int)tolua_tonumber(LuaState, 2, 0); int Max = (int)tolua_tonumber(LuaState, 3, 0); int Result = std::min(std::max(Min, Number), Max); -- cgit v1.2.3 From 40e15c5ad517a6f860b39d1b225596424c3d2506 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 5 Aug 2014 18:37:00 +0200 Subject: RankMgr: Initial interface declaration. --- src/CMakeLists.txt | 2 + src/RankManager.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/RankManager.h | 103 +++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 src/RankManager.cpp create mode 100644 src/RankManager.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db9c61082..d6066b38b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,6 +52,7 @@ SET (SRCS MonsterConfig.cpp Noise.cpp ProbabDistrib.cpp + RankManager.cpp RCONServer.cpp Root.cpp Scoreboard.cpp @@ -121,6 +122,7 @@ SET (HDRS MonsterConfig.h Noise.h ProbabDistrib.h + RankManager.h RCONServer.h Root.h Scoreboard.h diff --git a/src/RankManager.cpp b/src/RankManager.cpp new file mode 100644 index 000000000..954edd099 --- /dev/null +++ b/src/RankManager.cpp @@ -0,0 +1,153 @@ + +// RankManager.cpp + +// Implements the cRankManager class that represents the rank manager responsible for assigning permissions and message visuals to players + +#include "Globals.h" +#include "RankManager.h" +#include "Protocol/MojangAPI.h" +#include "inifile/iniFile.h" +#include + + + + + +/* +// This code is for internal testing while developing the cRankManager class +static class cRankMgrTest +{ +public: + cRankMgrTest(void) : + m_Mgr() + { + // Initialize the cMojangAPI so that it can convert playernames to UUIDs: + cIniFile Ini; + Ini.ReadFile("settings.ini"); + m_API.Start(Ini); + + // Test the cRankManager class: + ReportPlayer("xoft"); + } + + void ReportPlayer(const AString & a_PlayerName) + { + // Get the player's UUID and rank: + AString UUID = m_API.GetUUIDFromPlayerName(a_PlayerName); + std::cout << "Player " << a_PlayerName << " has UUID '" << UUID <<"'." << std::endl; + std::cout << " Rank: '" << m_Mgr.GetPlayerRankName(UUID) << "'." << std::endl; + + // List all the permission groups for the player: + AStringVector Groups = m_Mgr.GetPlayerPermissionGroups(UUID); + std::cout << " Groups(" << Groups.size() << "):" << std::endl; + for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) + { + std::cout << " '" << *itr << "'." << std::endl; + } // for itr - Groups[] + + // List all the permissions for the player: + AStringVector Permissions = m_Mgr.GetPlayerPermissions(UUID); + std::cout << " Permissions(" << Permissions.size() << "):" << std::endl; + for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) + { + std::cout << " '" << *itr << "'." << std::endl; + } // for itr - Groups[] + + std::cout << "Done." << std::endl; + } + +protected: + cRankManager m_Mgr; + cMojangAPI m_API; +} g_RankMgrTest; +//*/ + + + + + +cRankManager::cRankManager(void) : + m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) +{ + // Create the DB tables, if they don't exist: + m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID, Name, MsgPrefix, MsgPostfix, MsgNameColorCode)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionGroup (GroupID, Name)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermissionGroups (RankID, GroupID)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (GroupID, Permission)"); + + // TODO: Check if tables empty, add some defaults then +} + + + + + +AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) +{ + SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); + stmt.bind(1, a_PlayerUUID); + stmt.executeStep(); + if (stmt.isDone()) + { + // No data returned from the DB + return AString(); + } + return stmt.getColumn(0).getText(); +} + + + + + +AStringVector cRankManager::GetPlayerPermissionGroups(const AString & a_PlayerUUID) +{ + // Prepare the DB statement: + SQLite::Statement stmt(m_DB, + "SELECT PermissionGroup.Name FROM PermissionGroup " + "LEFT JOIN RankPermissionGroups " + "ON PermissionGroup.GroupID = RankPermissionGroups.GroupID " + "LEFT JOIN PlayerRank " + "ON PlayerRank.RankID = RankPermissionGroups.RankID " + "WHERE PlayerRank.PlayerUUID = ?" + ); + stmt.bind(1, a_PlayerUUID); + + // Execute and get results: + AStringVector res; + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + return res; +} + + + + + +AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) +{ + // Prepare the DB statement: + SQLite::Statement stmt(m_DB, + "SELECT PermissionItem.Permission FROM PermissionItem " + "LEFT JOIN RankPermissionGroups " + "ON PermissionItem.GroupID = RankPermissionGroups.GroupID " + "LEFT JOIN PlayerRank " + "ON PlayerRank.RankID = RankPermissionGroups.RankID " + "WHERE PlayerRank.PlayerUUID = ?" + ); + stmt.bind(1, a_PlayerUUID); + + // Execute and get results: + AStringVector res; + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + return res; +} + + + + diff --git a/src/RankManager.h b/src/RankManager.h new file mode 100644 index 000000000..cda6beee9 --- /dev/null +++ b/src/RankManager.h @@ -0,0 +1,103 @@ + +// RankManager.h + +// Declares the cRankManager class that represents the rank manager responsible for assigning permissions and message visuals to players + + + + +#pragma once + +#include "SQLiteCpp/Database.h" + + + + + +class cRankManager +{ +public: + cRankManager(void); + + /** Returns the name of the rank that the specified player has assigned to them. */ + AString GetPlayerRankName(const AString & a_PlayerUUID); + + /** Returns the names of PermissionGroups that the specified player has assigned to them. */ + AStringVector GetPlayerPermissionGroups(const AString & a_PlayerUUID); + + /** Returns the permissions that the specified player has assigned to them. */ + AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); + + /** Returns the names of groups that the specified rank has assigned to it. */ + AStringVector GetRankPermissionGroups(const AString & a_RankName); + + /** Returns the permissions that the specified permission group has assigned to it. */ + AStringVector GetPermissionGroupPermissiont(const AString & a_GroupName); + + /** Returns the names of all defined ranks. */ + AStringVector GetAllRanks(void); + + /** Returns the names of all permission groups. */ + AStringVector GetAllPermissionGroups(void); + + /** Returns all the distinct permissions that are stored in the DB. */ + AStringVector GetAllPermissions(void); + + /** Returns the message visuals (prefix, postfix, color) for the specified player. */ + void GetPlayerMsgVisuals( + const AString & a_PlayerUUID, + AString & a_MsgPrefix, + AString & a_MsgPostfix, + AString & a_MsgNameColorCode + ); + + /** Adds a new rank. No action if the rank already exists. */ + void AddRank(const AString & a_RankName); + + /** Adds a new permission group. No action if such a group already exists. */ + void AddPermissionGroup(const AString & a_GroupName); + + /** Adds the specified permission group to the specified rank. + Fails if the rank or group names are not found. + Returns true if successful, false on error. */ + bool AddPermissionGroupToRank(const AString & a_RankName, const AString & a_GroupName); + + /** Adds the specified permission to the specified permission group. + Fails if the permission group name is not found. + Returns true if successful, false on error. */ + bool AddPermissionToPermissionGroup(const AString & a_Permission, const AString & a_GroupName); + + /** Removes the specified rank. + All players assigned to that rank will be re-assigned to a_ReplacementRankName, unless it is empty. */ + void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); + + /** Removes the specified permission group. */ + void RemovePermissionGroup(const AString & a_PermissionGroup); + + /** Removes the specified permission from the specified permission group. */ + void RemovePermission(const AString & a_Permission, const AString & a_PermissionGroup); + + /** Renames the specified rank. No action if the rank name is not found. + Fails if the new name is already used. + Returns true on success, false on failure. */ + bool RenameRank(const AString & a_OldName, const AString & a_NewName); + + /** Renames the specified permission group. No action if the rank name is not found. + Fails if the new name is already used. + Returns true on success, false on failure. */ + bool RenamePermissionGroup(const AString & a_OldName, const AString & a_NewName); + + /** Sets the specified player's rank. + If the player already had rank assigned to them, it is overwritten with the new rank. + Note that this doesn't change the cPlayer if the player is already connected, you need to update all the + cPlayer instances manually. */ + void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_RankName); + +protected: + + SQLite::Database m_DB; +} ; + + + + -- cgit v1.2.3 From 5f04488a97b5cdd705368937d977827ef4465d4a Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 5 Aug 2014 18:39:18 +0200 Subject: Made lua clamp() compatible with all number types. --- src/Bindings/ManualBindings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 81065a7e1..9ba1501c5 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -96,11 +96,11 @@ static int tolua_Clamp(lua_State * tolua_S) return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); } - int Number = (int)tolua_tonumber(LuaState, 1, 0); - int Min = (int)tolua_tonumber(LuaState, 2, 0); - int Max = (int)tolua_tonumber(LuaState, 3, 0); + lua_Number Number = tolua_tonumber(LuaState, 1, 0); + lua_Number Min = tolua_tonumber(LuaState, 2, 0); + lua_Number Max = tolua_tonumber(LuaState, 3, 0); - int Result = std::min(std::max(Min, Number), Max); + lua_Number Result = Clamp(Number, Min, Max); LuaState.Push(Result); return 1; } -- cgit v1.2.3 From fcfae0252503a845c98fe6e882dda69e44224094 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 5 Aug 2014 22:28:37 +0200 Subject: RankMgr: More interface. --- src/RankManager.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/RankManager.h b/src/RankManager.h index cda6beee9..1eaeb97a1 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -47,12 +47,17 @@ public: void GetPlayerMsgVisuals( const AString & a_PlayerUUID, AString & a_MsgPrefix, - AString & a_MsgPostfix, + AString & a_MsgSuffix, AString & a_MsgNameColorCode ); /** Adds a new rank. No action if the rank already exists. */ - void AddRank(const AString & a_RankName); + void AddRank( + const AString & a_RankName, + const AString & a_MsgPrefix, + const AString & a_MsgSuffix, + const AString & a_MsgNameColorCode + ); /** Adds a new permission group. No action if such a group already exists. */ void AddPermissionGroup(const AString & a_GroupName); @@ -93,6 +98,13 @@ public: cPlayer instances manually. */ void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_RankName); + /** Sets the message visuals of an existing rank. No action if the rank name is not found. */ + void SetRankVisuals( + const AString & a_RankName, + const AString & a_MsgPrefix, + const AString & a_MsgSuffix, + const AString & a_MsgNameColorCode + ); protected: SQLite::Database m_DB; -- cgit v1.2.3 From a717a7e712e6be1e6980cade95f09b5b85bdfe67 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 5 Aug 2014 22:32:26 +0200 Subject: RankMgr: Added SQL integer datatypes. --- src/RankManager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 954edd099..18ed65b26 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -70,11 +70,11 @@ cRankManager::cRankManager(void) : m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) { // Create the DB tables, if they don't exist: - m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID, Name, MsgPrefix, MsgPostfix, MsgNameColorCode)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionGroup (GroupID, Name)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermissionGroups (RankID, GroupID)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (GroupID, Permission)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgPostfix, MsgNameColorCode)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID INTEGER)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionGroup (GroupID INTEGER PRIMARY KEY, Name)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermissionGroups (RankID INTEGER, GroupID INTEGER)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (GroupID INTEGER, Permission)"); // TODO: Check if tables empty, add some defaults then } -- cgit v1.2.3 From 06942871dde1388284a4fe222040720de3923b03 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 5 Aug 2014 21:48:23 +0100 Subject: Refactored Redstone simulator not to depend on TNTEntity or DropSpenserENtity Directly --- src/BlockEntities/DropSpenserEntity.h | 7 +++--- src/BlockEntities/RedstonePoweredEntity.h | 9 +++++++ src/Chunk.cpp | 34 ++++++++++++++++++++++++++ src/Chunk.h | 6 ++++- src/Simulator/IncrementalRedstoneSimulator.cpp | 9 +++---- 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 src/BlockEntities/RedstonePoweredEntity.h (limited to 'src') diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index 9f58d0b07..dabe9a27b 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -11,7 +11,7 @@ #pragma once #include "BlockEntityWithItems.h" - +#include "RedstonePoweredEntity.h" @@ -30,7 +30,8 @@ class cServer; // tolua_begin class cDropSpenserEntity : - public cBlockEntityWithItems + public cBlockEntityWithItems, + public cRedstonePoweredEntity { typedef cBlockEntityWithItems super; @@ -65,7 +66,7 @@ public: void Activate(void); /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate - void SetRedstonePower(bool a_IsPowered); + virtual void SetRedstonePower(bool a_IsPowered) override; // tolua_end diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h new file mode 100644 index 000000000..aebba771f --- /dev/null +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -0,0 +1,9 @@ + + +// Interface class representing a blockEntity that responds to redstone +class cRedstonePoweredEntity +{ +public: +/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate + virtual void SetRedstonePower(bool a_IsPowered) = 0; +}; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index cd7dc698c..9e06f58ec 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2127,6 +2127,40 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc +bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback) +{ + // The blockentity list is locked by the parent chunkmap's CS + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) + { + ++itr2; + if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ)) + { + continue; + } + switch ((*itr)->GetBlockType()) + { + case E_BLOCK_DROPPER: + case E_BLOCK_DISPENSER: + break; + default: + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; + } + + if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) + { + return false; + } + return true; + } // for itr - m_BlockEntitites[] + + // Not found: + return false; +} + + + + bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback) { // The blockentity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index 5cde3f08f..813a8b13f 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -43,6 +43,7 @@ class cBlockArea; class cFluidSimulatorData; class cMobCensus; class cMobSpawner; +class cRedstonePoweredEntity; typedef std::list cClientHandleList; typedef cItemCallback cEntityCallback; @@ -54,6 +55,7 @@ typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; typedef cItemCallback cMobHeadCallback; typedef cItemCallback cFlowerPotCallback; +typedef cItemCallback cRedstonePoweredCallback; @@ -237,7 +239,9 @@ public: /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible - + + /** Calls the callback for the redstone powered entity at the specified coords; returns false if there's no redstone powered entity at those coords, true if found */ + bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index c1a2fcaae..5b2439db1 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -3,11 +3,10 @@ #include "IncrementalRedstoneSimulator.h" #include "BoundingBox.h" -#include "../BlockEntities/DropSpenserEntity.h" +#include "../BlockEntities/RedstonePoweredEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" -#include "../Entities/TNTEntity.h" #include "../Entities/Pickup.h" #include "../Blocks/BlockTorch.h" #include "../Blocks/BlockDoor.h" @@ -842,13 +841,13 @@ void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlock void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { class cSetPowerToDropSpenser : - public cDropSpenserCallback + public cRedstonePoweredCallback { bool m_IsPowered; public: cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - virtual bool Item(cDropSpenserEntity * a_DropSpenser) override + virtual bool Item(cRedstonePoweredEntity * a_DropSpenser) override { a_DropSpenser->SetRedstonePower(m_IsPowered); return false; @@ -857,7 +856,7 @@ void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_Rel int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithDropSpenserAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); } -- cgit v1.2.3 From 9272bd627c732771b81e6dcf6b8465404917a9d6 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 5 Aug 2014 22:54:36 +0100 Subject: Removed dependecy of redstone simulator on NoteBlock --- src/BlockEntities/NoteEntity.h | 10 +++++++++- src/BlockEntities/RedstonePoweredEntity.h | 4 ++++ src/Chunk.cpp | 1 + src/Simulator/IncrementalRedstoneSimulator.cpp | 17 ++++++----------- 4 files changed, 20 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index e8497da3e..f9db6cbe6 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -2,6 +2,7 @@ #pragma once #include "BlockEntity.h" +#include "RedstonePoweredEntity.h" namespace Json @@ -29,7 +30,8 @@ enum ENUM_NOTE_INSTRUMENTS // tolua_begin class cNoteEntity : - public cBlockEntity + public cBlockEntity, + public cRedstonePoweredEntity { typedef cBlockEntity super; public: @@ -38,6 +40,7 @@ public: /// Creates a new note entity. a_World may be NULL cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); + virtual ~cNoteEntity() {} bool LoadFromJson(const Json::Value & a_Value); virtual void SaveToJson(Json::Value & a_Value) override; @@ -53,6 +56,11 @@ public: virtual void UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle &) override {} + + virtual void SetRedstonePower(bool a_Value) + { + if (a_Value) MakeSound(); + } static const char * GetClassStatic(void) { return "cNoteEntity"; } diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h index aebba771f..7d6904442 100644 --- a/src/BlockEntities/RedstonePoweredEntity.h +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -1,9 +1,13 @@ +#pragma once // Interface class representing a blockEntity that responds to redstone class cRedstonePoweredEntity { public: + + virtual ~cRedstonePoweredEntity() {}; + /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate virtual void SetRedstonePower(bool a_IsPowered) = 0; }; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 9e06f58ec..1e8d0e6f0 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2141,6 +2141,7 @@ bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_Blo { case E_BLOCK_DROPPER: case E_BLOCK_DISPENSER: + case E_BLOCK_NOTE_BLOCK: break; default: // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 5b2439db1..7b3a2c2fa 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -4,7 +4,6 @@ #include "IncrementalRedstoneSimulator.h" #include "BoundingBox.h" #include "../BlockEntities/RedstonePoweredEntity.h" -#include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../Entities/Pickup.h" @@ -1033,25 +1032,21 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBl if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) { class cSetPowerToNoteBlock : - public cNoteBlockCallback + public cRedstonePoweredCallback { - bool m_IsPowered; public: - cSetPowerToNoteBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + cSetPowerToNoteBlock() {} - virtual bool Item(cNoteEntity * a_NoteBlock) override + virtual bool Item(cRedstonePoweredEntity * a_NoteBlock) override { - if (m_IsPowered) - { - a_NoteBlock->MakeSound(); - } + a_NoteBlock->SetRedstonePower(true); return false; } - } NoteBlockSP(m_bAreCoordsPowered); + } NoteBlockSP; int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithNoteBlockAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); } } -- cgit v1.2.3 From ff7171fc5a567590dd52d4213439778f0dfcce53 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 6 Aug 2014 14:04:25 +0200 Subject: Resending fire to the client when the interact cancelled. --- src/ClientHandle.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 72257028a..3e046f38d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -920,6 +920,10 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB ) { m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + } return; } @@ -928,6 +932,10 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB { // A plugin doesn't agree with the action, replace the block on the client and quit: m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + } return; } -- cgit v1.2.3 From a0ba7426c6bc2059d5db6d248ef8e582e40ce4b3 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 6 Aug 2014 13:17:05 +0100 Subject: Fixed multiple inhertance being output by tolua --- src/BlockEntities/DropSpenserEntity.h | 10 ++++++---- src/BlockEntities/NoteEntity.h | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index dabe9a27b..be56447aa 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -30,8 +30,10 @@ class cServer; // tolua_begin class cDropSpenserEntity : - public cBlockEntityWithItems, - public cRedstonePoweredEntity + public cBlockEntityWithItems + // tolua_end + , public cRedstonePoweredEntity + // tolua_begin { typedef cBlockEntityWithItems super; @@ -65,10 +67,10 @@ public: /// Sets the dropspenser to dropspense an item in the next tick void Activate(void); + // tolua_end + /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate virtual void SetRedstonePower(bool a_IsPowered) override; - - // tolua_end protected: bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index f9db6cbe6..dd201e0a9 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -30,8 +30,10 @@ enum ENUM_NOTE_INSTRUMENTS // tolua_begin class cNoteEntity : - public cBlockEntity, - public cRedstonePoweredEntity + public cBlockEntity + // tolua_end + , public cRedstonePoweredEntity + // tolua_begin { typedef cBlockEntity super; public: -- cgit v1.2.3 From 6acddd0cad25078ae2c67e7a0eb353e9d4d100e2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 6 Aug 2014 13:19:22 +0100 Subject: Fixed style issues --- src/BlockEntities/NoteEntity.h | 5 ++++- src/BlockEntities/RedstonePoweredEntity.h | 2 +- src/Chunk.cpp | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index dd201e0a9..f538de060 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -61,7 +61,10 @@ public: virtual void SetRedstonePower(bool a_Value) { - if (a_Value) MakeSound(); + if (a_Value) + { + MakeSound(); + } } static const char * GetClassStatic(void) { return "cNoteEntity"; } diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h index 7d6904442..f11df4fc4 100644 --- a/src/BlockEntities/RedstonePoweredEntity.h +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -8,6 +8,6 @@ public: virtual ~cRedstonePoweredEntity() {}; -/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate + /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate virtual void SetRedstonePower(bool a_IsPowered) = 0; }; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 1e8d0e6f0..a79a485a6 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2142,10 +2142,10 @@ bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_Blo case E_BLOCK_DROPPER: case E_BLOCK_DISPENSER: case E_BLOCK_NOTE_BLOCK: - break; + break; default: - // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out - return false; + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; } if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) -- cgit v1.2.3 From beab61bbfeca0280bce941c4175837109282c828 Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 6 Aug 2014 14:16:36 -0700 Subject: On destroy ender crystal, create bedrock and fire --- src/Entities/EnderCrystal.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp index bf86a6c42..c17bb608e 100644 --- a/src/Entities/EnderCrystal.cpp +++ b/src/Entities/EnderCrystal.cpp @@ -32,9 +32,6 @@ void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk) { UNUSED(a_Dt); - - a_Chunk.SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0); - // No further processing (physics e.t.c.) is needed } @@ -49,6 +46,9 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI) m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this); Destroy(); + + m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_BEDROCK, 0); + m_World->SetBlock(POSX_TOINT, POSY_TOINT + 1, POSZ_TOINT, E_BLOCK_FIRE, 0); } -- cgit v1.2.3 From 4271d719b68521f91770574b3064525512116670 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 7 Aug 2014 01:07:32 +0200 Subject: Added SetDoDaylightCycle() and IsDaylightCycleEnabled() to cWorld. I need this for a GameRule plugin. --- src/ClientHandle.cpp | 11 ++++++++++- src/ClientHandle.h | 2 +- src/World.cpp | 49 ++++++++++++++++++++++++++++++++----------------- src/World.h | 14 +++++++++++++- 4 files changed, 56 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3e046f38d..286c17513 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -342,7 +342,16 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, } // Send time - m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay()); + Int64 TimeOfDay = World->GetTimeOfDay(); + if (!World->IsDaylightCycleEnabled()) + { + TimeOfDay *= -1; + if (TimeOfDay == 0) + { + TimeOfDay = -1; + } + } + m_Protocol->SendTimeUpdate(World->GetWorldAge(), TimeOfDay); // Send contents of the inventory window m_Protocol->SendWholeInventory(*m_Player->GetWindow()); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index ee1db3155..1bf397ad2 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -179,7 +179,7 @@ public: void SendTabCompletionResults(const AStringVector & a_Results); void SendTeleportEntity (const cEntity & a_Entity); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); - void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); + void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); // tolua_export void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); diff --git a/src/World.cpp b/src/World.cpp index d2213d1e5..7ed8bc1e4 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -243,6 +243,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin #endif m_Dimension(a_Dimension), m_IsSpawnExplicitlySet(false), + m_DoDaylightCycle(true), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -827,28 +828,32 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) { SetChunkData(**itr); } // for itr - SetChunkDataQueue[] - - // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it + m_WorldAgeSecs += (double)a_Dt / 1000.0; - m_TimeOfDaySecs += (double)a_Dt / 1000.0; + m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - // Wrap time of day each 20 minutes (1200 seconds) - if (m_TimeOfDaySecs > 1200.0) + if (m_DoDaylightCycle) { - m_TimeOfDaySecs -= 1200.0; - } + // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it + m_TimeOfDaySecs += (double)a_Dt / 1000.0; - m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); + // Wrap time of day each 20 minutes (1200 seconds) + if (m_TimeOfDaySecs > 1200.0) + { + m_TimeOfDaySecs -= 1200.0; + } - // Updates the sky darkness based on current time of day - UpdateSkyDarkness(); + m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); - // Broadcast time update every 40 ticks (2 seconds) - if (m_LastTimeUpdate < m_WorldAge - 40) - { - BroadcastTimeUpdate(); - m_LastTimeUpdate = m_WorldAge; + // Updates the sky darkness based on current time of day + UpdateSkyDarkness(); + + // Broadcast time update every 40 ticks (2 seconds) + if (m_LastTimeUpdate < m_WorldAge - 40) + { + BroadcastTimeUpdate(); + m_LastTimeUpdate = m_WorldAge; + } } // Add entities waiting in the queue to be added: @@ -2243,6 +2248,16 @@ void cWorld::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { + int TimeOfDay = m_TimeOfDay; + if (!m_DoDaylightCycle) + { + TimeOfDay *= -1; + if (TimeOfDay == 0) + { + TimeOfDay = -1; + } + } + cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { @@ -2251,7 +2266,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { continue; } - ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay); + ch->SendTimeUpdate(m_WorldAge, TimeOfDay); } } diff --git a/src/World.h b/src/World.h index 90b798e8e..8ddc69118 100644 --- a/src/World.h +++ b/src/World.h @@ -145,7 +145,17 @@ public: // tolua_begin int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } - + + /** Is the daylight cyclus enabled? */ + virtual bool IsDaylightCycleEnabled(void) const { return m_DoDaylightCycle; } + + /** Sets the daylight cyclus to true/false. */ + virtual void SetDoDaylightCycle(bool a_DoDaylightCycle) + { + m_DoDaylightCycle = a_DoDaylightCycle; + BroadcastTimeUpdate(); + } + virtual Int64 GetWorldAge (void) const override { return m_WorldAge; } virtual Int64 GetTimeOfDay(void) const override { return m_TimeOfDay; } @@ -158,6 +168,7 @@ public: { m_TimeOfDay = a_TimeOfDay; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; + UpdateSkyDarkness(); BroadcastTimeUpdate(); } @@ -868,6 +879,7 @@ private: bool m_BroadcastDeathMessages; bool m_BroadcastAchievementMessages; + bool m_DoDaylightCycle; // Is the daylight cyclus enabled? double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs -- cgit v1.2.3 From 0c622522ea52ed07aa12a25827b498acd290b531 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 7 Aug 2014 01:08:31 +0200 Subject: Removed debug message. --- src/Bindings/ManualBindings.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9ba1501c5..8e6156d97 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -507,7 +507,6 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0)); int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0)); - LOG("x %i y %i z %i", ItemX, ItemY, ItemZ); if (!lua_isfunction( tolua_S, 5)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4"); -- cgit v1.2.3 From a73c85d7eb8181b3792f19675c29f43bd8c0b738 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 7 Aug 2014 02:42:42 +0200 Subject: Fixed nether wart digging. Fixes #1265 --- src/BlockInfo.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 4bc3fbbdc..a59229f87 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -294,6 +294,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; a_Info[E_BLOCK_LILY_PAD ].m_OneHitDig = true; a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; + a_Info[E_BLOCK_NETHER_WART ].m_OneHitDig = true; a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; -- cgit v1.2.3 From 670e94bfeb62a51ca64ffaa0e45086e1ca91057c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 09:56:28 +0200 Subject: RankMgr: Renamed PermissionGroup to Group in API and PermGroup in DB. "Group" is SQL keyword and shouldn't be used as table name. --- src/RankManager.cpp | 26 +++++++++++++------------- src/RankManager.h | 38 +++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 18ed65b26..e77fb22b9 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -13,7 +13,7 @@ -/* +//* // This code is for internal testing while developing the cRankManager class static class cRankMgrTest { @@ -38,7 +38,7 @@ public: std::cout << " Rank: '" << m_Mgr.GetPlayerRankName(UUID) << "'." << std::endl; // List all the permission groups for the player: - AStringVector Groups = m_Mgr.GetPlayerPermissionGroups(UUID); + AStringVector Groups = m_Mgr.GetPlayerGroups(UUID); std::cout << " Groups(" << Groups.size() << "):" << std::endl; for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) { @@ -72,9 +72,9 @@ cRankManager::cRankManager(void) : // Create the DB tables, if they don't exist: m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgPostfix, MsgNameColorCode)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID INTEGER)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionGroup (GroupID INTEGER PRIMARY KEY, Name)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermissionGroups (RankID INTEGER, GroupID INTEGER)"); - m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (GroupID INTEGER, Permission)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermGroup (PermGroupID INTEGER PRIMARY KEY, Name)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermGroup (RankID INTEGER, PermGroupID INTEGER)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (PermGroupID INTEGER, Permission)"); // TODO: Check if tables empty, add some defaults then } @@ -100,15 +100,15 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) -AStringVector cRankManager::GetPlayerPermissionGroups(const AString & a_PlayerUUID) +AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { // Prepare the DB statement: SQLite::Statement stmt(m_DB, - "SELECT PermissionGroup.Name FROM PermissionGroup " - "LEFT JOIN RankPermissionGroups " - "ON PermissionGroup.GroupID = RankPermissionGroups.GroupID " + "SELECT Group.Name FROM Group " + "LEFT JOIN RankGroups " + "ON Group.GroupID = RankGroups.GroupID " "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankPermissionGroups.RankID " + "ON PlayerRank.RankID = RankGroups.RankID " "WHERE PlayerRank.PlayerUUID = ?" ); stmt.bind(1, a_PlayerUUID); @@ -131,10 +131,10 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) // Prepare the DB statement: SQLite::Statement stmt(m_DB, "SELECT PermissionItem.Permission FROM PermissionItem " - "LEFT JOIN RankPermissionGroups " - "ON PermissionItem.GroupID = RankPermissionGroups.GroupID " + "LEFT JOIN RankGroups " + "ON PermissionItem.GroupID = RankGroups.GroupID " "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankPermissionGroups.RankID " + "ON PlayerRank.RankID = RankGroups.RankID " "WHERE PlayerRank.PlayerUUID = ?" ); stmt.bind(1, a_PlayerUUID); diff --git a/src/RankManager.h b/src/RankManager.h index 1eaeb97a1..0b1db2fb8 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -22,23 +22,26 @@ public: /** Returns the name of the rank that the specified player has assigned to them. */ AString GetPlayerRankName(const AString & a_PlayerUUID); - /** Returns the names of PermissionGroups that the specified player has assigned to them. */ - AStringVector GetPlayerPermissionGroups(const AString & a_PlayerUUID); + /** Returns the names of Groups that the specified player has assigned to them. */ + AStringVector GetPlayerGroups(const AString & a_PlayerUUID); /** Returns the permissions that the specified player has assigned to them. */ AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); /** Returns the names of groups that the specified rank has assigned to it. */ - AStringVector GetRankPermissionGroups(const AString & a_RankName); + AStringVector GetRankGroups(const AString & a_RankName); - /** Returns the permissions that the specified permission group has assigned to it. */ - AStringVector GetPermissionGroupPermissiont(const AString & a_GroupName); + /** Returns the permissions that the specified group has assigned to it. */ + AStringVector GetGroupPermissions(const AString & a_GroupName); + + /** Returns all permissions that the specified rank has assigned to it, through all its groups. */ + AStringVector GetRankPermissions(const AString & a_RankName); /** Returns the names of all defined ranks. */ AStringVector GetAllRanks(void); /** Returns the names of all permission groups. */ - AStringVector GetAllPermissionGroups(void); + AStringVector GetAllGroups(void); /** Returns all the distinct permissions that are stored in the DB. */ AStringVector GetAllPermissions(void); @@ -60,37 +63,42 @@ public: ); /** Adds a new permission group. No action if such a group already exists. */ - void AddPermissionGroup(const AString & a_GroupName); + void AddGroup(const AString & a_GroupName); /** Adds the specified permission group to the specified rank. Fails if the rank or group names are not found. Returns true if successful, false on error. */ - bool AddPermissionGroupToRank(const AString & a_RankName, const AString & a_GroupName); + bool AddGroupToRank(const AString & a_RankName, const AString & a_GroupName); /** Adds the specified permission to the specified permission group. Fails if the permission group name is not found. Returns true if successful, false on error. */ - bool AddPermissionToPermissionGroup(const AString & a_Permission, const AString & a_GroupName); + bool AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName); /** Removes the specified rank. All players assigned to that rank will be re-assigned to a_ReplacementRankName, unless it is empty. */ void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); - /** Removes the specified permission group. */ - void RemovePermissionGroup(const AString & a_PermissionGroup); + /** Removes the specified group completely. + The group will first be removed from all ranks using it, and then removed itself. */ + void RemoveGroup(const AString & a_GroupName); + + /** Removes the specified group from the specified rank. + The group will stay defined, even if no rank is using it. */ + void RemoveGroupFromRank(const AString & a_RankName, const AString & a_GroupName); - /** Removes the specified permission from the specified permission group. */ - void RemovePermission(const AString & a_Permission, const AString & a_PermissionGroup); + /** Removes the specified permission from the specified group. */ + void RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName); /** Renames the specified rank. No action if the rank name is not found. Fails if the new name is already used. Returns true on success, false on failure. */ bool RenameRank(const AString & a_OldName, const AString & a_NewName); - /** Renames the specified permission group. No action if the rank name is not found. + /** Renames the specified group. No action if the rank name is not found. Fails if the new name is already used. Returns true on success, false on failure. */ - bool RenamePermissionGroup(const AString & a_OldName, const AString & a_NewName); + bool RenameGroup(const AString & a_OldName, const AString & a_NewName); /** Sets the specified player's rank. If the player already had rank assigned to them, it is overwritten with the new rank. -- cgit v1.2.3 From 65b81b4ab7f580c98ca80b8e57a13de961f19131 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 10:02:25 +0200 Subject: RankMgr: Implemented the basic API functions. --- src/RankManager.cpp | 738 +++++++++++++++++++++++++++++++++++++++++++++++----- src/RankManager.h | 18 +- 2 files changed, 696 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index e77fb22b9..e02e63a24 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -5,15 +5,13 @@ #include "Globals.h" #include "RankManager.h" -#include "Protocol/MojangAPI.h" -#include "inifile/iniFile.h" -#include +#include "SQLiteCpp/Transaction.h" -//* +/* // This code is for internal testing while developing the cRankManager class static class cRankMgrTest { @@ -21,44 +19,72 @@ public: cRankMgrTest(void) : m_Mgr() { - // Initialize the cMojangAPI so that it can convert playernames to UUIDs: - cIniFile Ini; - Ini.ReadFile("settings.ini"); - m_API.Start(Ini); + // Initialize logging: + new cMCLogger(); + AString UUID = "b1caf24202a841a78055a079c460eee7"; // UUID for "xoft" + LOG("Testing UUID %s", UUID.c_str()); - // Test the cRankManager class: - ReportPlayer("xoft"); + // Test the initial state of the ranks: + LOG("Initial test:"); + ReportPlayer(UUID); + + // Add a rank, a few groups and permissions and set the player to use them: + LOG("Adding data..."); + m_Mgr.AddRank("TestRank", "[test]", "[/test]", "7"); + m_Mgr.AddGroup("TestGroup1"); + m_Mgr.AddGroup("TestGroup2"); + m_Mgr.AddGroupToRank("TestGroup1", "TestRank"); + m_Mgr.AddGroupToRank("TestGroup2", "TestRank"); + m_Mgr.AddPermissionToGroup("testpermission1.1", "TestGroup1"); + m_Mgr.AddPermissionToGroup("testpermission1.2", "TestGroup1"); + m_Mgr.AddPermissionToGroup("testpermission2.1", "TestGroup2"); + m_Mgr.SetPlayerRank(UUID, "TestRank"); + + // Test the added data: + LOG("Testing the added data:"); + LOG("IsGroupInRank(TestGroup1, TestRank) = %s", m_Mgr.IsGroupInRank("TestGroup1", "TestRank") ? "true" : "false"); + LOG("IsGroupInRank(TestGroup3, TestRank) = %s", m_Mgr.IsGroupInRank("TestGroup3", "TestRank") ? "true" : "false"); + LOG("IsPermissionInGroup(testpermission1.2, TestGroup1) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup1") ? "true" : "false"); + LOG("IsPermissionInGroup(testpermission1.2, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup2") ? "true" : "false"); + LOG("IsPermissionInGroup(testpermission1.3, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.3", "TestGroup2") ? "true" : "false"); + LOG("IsPlayerRankSet(%s) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID) ? "true" : "false"); + LOG("IsPlayerRankSet(%s1) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID + "1") ? "true" : "false"); + LOG("GroupExists(TestGroup1) = %s", m_Mgr.GroupExists("TestGroup1") ? "true" : "false"); + LOG("GroupExists(TestGroup3) = %s", m_Mgr.GroupExists("TestGroup3") ? "true" : "false"); + LOG("RankExists(TestRank) = %s", m_Mgr.RankExists("TestRank") ? "true" : "false"); + LOG("RankExists(NonexistentRank) = %s", m_Mgr.RankExists("NonexistentRank") ? "true" : "false"); + + // Test the assignments above: + LOG("After-assignment test:"); + ReportPlayer(UUID); + + LOG("Done."); } - void ReportPlayer(const AString & a_PlayerName) + void ReportPlayer(const AString & a_PlayerUUID) { // Get the player's UUID and rank: - AString UUID = m_API.GetUUIDFromPlayerName(a_PlayerName); - std::cout << "Player " << a_PlayerName << " has UUID '" << UUID <<"'." << std::endl; - std::cout << " Rank: '" << m_Mgr.GetPlayerRankName(UUID) << "'." << std::endl; + LOG(" Rank: '%s'", m_Mgr.GetPlayerRankName(a_PlayerUUID).c_str()); // List all the permission groups for the player: - AStringVector Groups = m_Mgr.GetPlayerGroups(UUID); - std::cout << " Groups(" << Groups.size() << "):" << std::endl; + AStringVector Groups = m_Mgr.GetPlayerGroups(a_PlayerUUID); + LOG(" Groups(%u):", (unsigned)Groups.size()); for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) { - std::cout << " '" << *itr << "'." << std::endl; + LOG(" '%s'" , itr->c_str()); } // for itr - Groups[] // List all the permissions for the player: - AStringVector Permissions = m_Mgr.GetPlayerPermissions(UUID); - std::cout << " Permissions(" << Permissions.size() << "):" << std::endl; + AStringVector Permissions = m_Mgr.GetPlayerPermissions(a_PlayerUUID); + LOG(" Permissions(%u):", (unsigned)Permissions.size()); for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) { - std::cout << " '" << *itr << "'." << std::endl; + LOG(" '%s'", itr->c_str()); } // for itr - Groups[] - - std::cout << "Done." << std::endl; } protected: cRankManager m_Mgr; - cMojangAPI m_API; } g_RankMgrTest; //*/ @@ -70,7 +96,7 @@ cRankManager::cRankManager(void) : m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) { // Create the DB tables, if they don't exist: - m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgPostfix, MsgNameColorCode)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgSuffix, MsgNameColorCode)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID INTEGER)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PermGroup (PermGroupID INTEGER PRIMARY KEY, Name)"); m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermGroup (RankID INTEGER, PermGroupID INTEGER)"); @@ -85,15 +111,23 @@ cRankManager::cRankManager(void) : AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { - SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); - stmt.bind(1, a_PlayerUUID); - stmt.executeStep(); - if (stmt.isDone()) + try { - // No data returned from the DB - return AString(); + SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); + stmt.bind(1, a_PlayerUUID); + stmt.executeStep(); + if (stmt.isDone()) + { + // No data returned from the DB + return AString(); + } + return stmt.getColumn(0).getText(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Cannot get player rank name: %s", __FUNCTION__, ex.what()); } - return stmt.getColumn(0).getText(); + return AString(); } @@ -102,22 +136,29 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { - // Prepare the DB statement: - SQLite::Statement stmt(m_DB, - "SELECT Group.Name FROM Group " - "LEFT JOIN RankGroups " - "ON Group.GroupID = RankGroups.GroupID " - "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankGroups.RankID " - "WHERE PlayerRank.PlayerUUID = ?" - ); - stmt.bind(1, a_PlayerUUID); - - // Execute and get results: AStringVector res; - while (stmt.executeStep()) + try { - res.push_back(stmt.getColumn(0).getText()); + // Prepare the DB statement: + SQLite::Statement stmt(m_DB, + "SELECT PermGroup.Name FROM PermGroup " + "LEFT JOIN RankPermGroup " + "ON PermGroup.PermGroupID = RankPermGroup.PermGroupID " + "LEFT JOIN PlayerRank " + "ON PlayerRank.RankID = RankPermGroup.RankID " + "WHERE PlayerRank.PlayerUUID = ?" + ); + stmt.bind(1, a_PlayerUUID); + + // Execute and get results: + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Cannot get player groups: %s", __FUNCTION__, ex.what()); } return res; } @@ -128,22 +169,29 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) { - // Prepare the DB statement: - SQLite::Statement stmt(m_DB, - "SELECT PermissionItem.Permission FROM PermissionItem " - "LEFT JOIN RankGroups " - "ON PermissionItem.GroupID = RankGroups.GroupID " - "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankGroups.RankID " - "WHERE PlayerRank.PlayerUUID = ?" - ); - stmt.bind(1, a_PlayerUUID); - - // Execute and get results: AStringVector res; - while (stmt.executeStep()) + try + { + // Prepare the DB statement: + SQLite::Statement stmt(m_DB, + "SELECT PermissionItem.Permission FROM PermissionItem " + "LEFT JOIN RankPermGroup " + "ON PermissionItem.PermGroupID = RankPermGroup.PermGroupID " + "LEFT JOIN PlayerRank " + "ON PlayerRank.RankID = RankPermGroup.RankID " + "WHERE PlayerRank.PlayerUUID = ?" + ); + stmt.bind(1, a_PlayerUUID); + + // Execute and get results: + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) { - res.push_back(stmt.getColumn(0).getText()); + LOGWARNING("%s: Cannot get player permissions: %s", __FUNCTION__, ex.what()); } return res; } @@ -151,3 +199,575 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) + +AStringVector cRankManager::GetRankGroups(const AString & a_RankName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyGroup", __FUNCTION__)); + return res; +} + + + + + +AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + return res; +} + + + + + +AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + return res; +} + + + + + +AStringVector cRankManager::GetAllRanks(void) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyRank", __FUNCTION__)); + return res; +} + + + + + +AStringVector cRankManager::GetAllGroups(void) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyGroup", __FUNCTION__)); + return res; +} + + + + + +AStringVector cRankManager::GetAllPermissions(void) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + return res; +} + + + + + +void cRankManager::GetPlayerMsgVisuals( + const AString & a_PlayerUUID, + AString & a_MsgPrefix, + AString & a_MsgSuffix, + AString & a_MsgNameColorCode +) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + a_MsgPrefix = Printf("%s: DummyPrefix", __FUNCTION__); + a_MsgSuffix = Printf("%s: DummySuffix", __FUNCTION__); + a_MsgNameColorCode = Printf("%s: DummyMsgNameColorCode", __FUNCTION__); +} + + + + + +void cRankManager::AddRank( + const AString & a_RankName, + const AString & a_MsgPrefix, + const AString & a_MsgSuffix, + const AString & a_MsgNameColorCode +) +{ + try + { + // Check if such a rank name is already used: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (stmt.executeStep()) + { + if (stmt.getColumn(0).getInt() > 0) + { + // Rank already exists, do nothing: + return; + } + } + } + + // Insert a new rank: + SQLite::Statement stmt(m_DB, "INSERT INTO Rank (Name, MsgPrefix, MsgSuffix, MsgNameColorCode) VALUES (?, ?, ?, ?)"); + stmt.bind(1, a_RankName); + stmt.bind(2, a_MsgPrefix); + stmt.bind(3, a_MsgSuffix); + stmt.bind(4, a_MsgNameColorCode); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add a new rank \"%s\".", __FUNCTION__, a_RankName.c_str()); + return; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add a new rank \"%s\": %s", __FUNCTION__, a_RankName.c_str(), ex.what()); + } +} + + + + + +void cRankManager::AddGroup(const AString & a_GroupName) +{ + try + { + // Check if such a rank name is already used: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (stmt.executeStep()) + { + if (stmt.getColumn(0).getInt() > 0) + { + // Group already exists, do nothing: + return; + } + } + } + + // Insert a new rank: + SQLite::Statement stmt(m_DB, "INSERT INTO PermGroup (Name) VALUES (?)"); + stmt.bind(1, a_GroupName); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add a new group \"%s\".", __FUNCTION__, a_GroupName.c_str()); + return; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add a new group \"%s\": %s", __FUNCTION__, a_GroupName.c_str(), ex.what()); + } +} + + + + + +bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a_RankName) +{ + try + { + SQLite::Transaction trans(m_DB); + int GroupID, RankID; + + // Get the group's ID: + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such group (%s), aborting.", __FUNCTION__, a_GroupName.c_str()); + return false; + } + GroupID = stmt.getColumn(0); + } + + // Get the rank's ID: + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such rank (%s), aborting.", __FUNCTION__, a_RankName.c_str()); + return false; + } + RankID = stmt.getColumn(0); + } + + // Check if the group is already there: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM RankPermGroup WHERE RankID = ? AND PermGroupID = ?"); + stmt.bind(1, RankID); + stmt.bind(2, GroupID); + if (!stmt.executeStep()) + { + LOGWARNING("%s: Failed to check binding between rank %s and group %s, aborting.", __FUNCTION__, a_RankName.c_str(), a_GroupName.c_str()); + return false; + } + if (stmt.getColumn(0).getInt() > 0) + { + LOGD("%s: Group %s already present in rank %s, skipping and returning success.", + __FUNCTION__, a_GroupName.c_str(), a_RankName.c_str() + ); + return true; + } + } + + // Add the group: + { + SQLite::Statement stmt(m_DB, "INSERT INTO RankPermGroup (RankID, PermGroupID) VALUES (?, ?)"); + stmt.bind(1, RankID); + stmt.bind(2, GroupID); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add group %s to rank %s, aborting.", __FUNCTION__, a_GroupName.c_str(), a_RankName.c_str()); + return false; + } + } + + // Adding succeeded: + trans.commit(); + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add group %s to rank %s: %s", __FUNCTION__, a_GroupName.c_str(), a_RankName.c_str(), ex.what()); + } + return false; +} + + + + + +bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName) +{ + try + { + // Wrapp the entire operation into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the group's ID: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such group (%s), aborting.", __FUNCTION__, a_GroupName.c_str()); + return false; + } + GroupID = stmt.getColumn(0).getInt(); + } + + // Check if the permission is already present: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermissionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, a_Permission); + if (!stmt.executeStep()) + { + LOGWARNING("%s: Failed to check binding between permission %s and group %s, aborting.", __FUNCTION__, a_Permission.c_str(), a_GroupName.c_str()); + return false; + } + if (stmt.getColumn(0).getInt() > 0) + { + LOGD("%s: Permission %s is already present in group %s, skipping and returning success.", + __FUNCTION__, a_Permission.c_str(), a_GroupName.c_str() + ); + return true; + } + } + + // Add the permission: + { + SQLite::Statement stmt(m_DB, "INSERT INTO PermissionItem (Permission, PermGroupID) VALUES (?, ?)"); + stmt.bind(1, a_Permission); + stmt.bind(2, GroupID); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add permission %s to group %s, aborting.", __FUNCTION__, a_Permission.c_str(), a_GroupName.c_str()); + return false; + } + } + + // Adding succeeded: + trans.commit(); + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add permission %s to group %s: %s", + __FUNCTION__, a_Permission.c_str(), a_GroupName.c_str(), ex.what() + ); + } + return false; +} + + + + + +void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + +void cRankManager::RemoveGroup(const AString & a_GroupName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + +void cRankManager::RemoveGroupFromRank(const AString & a_RankName, const AString & a_GroupName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + +void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + +bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + return false; +} + + + + + +bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewName) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); + return false; +} + + + + + +void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_RankName) +{ + try + { + // Wrap the entire operation into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the rank ID: + int RankID; + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: There is no rank %s, aborting.", __FUNCTION__, a_RankName.c_str()); + return; + } + RankID = stmt.getColumn(0).getInt(); + } + + // Update the player's rank, if already in DB: + { + SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ? WHERE PlayerUUID = ?"); + stmt.bind(1, RankID); + stmt.bind(2, a_PlayerUUID); + if (stmt.exec() > 0) + { + // Successfully updated the player's rank + trans.commit(); + return; + } + } + + // The player is not yet in the DB, add them: + SQLite::Statement stmt(m_DB, "INSERT INTO PlayerRank (RankID, PlayerUUID) VALUES (?, ?)"); + stmt.bind(1, RankID); + stmt.bind(2, a_PlayerUUID); + if (stmt.exec() > 0) + { + // Successfully added the player + trans.commit(); + return; + } + + LOGWARNING("%s: Failed to set player UUID %s to rank %s.", + __FUNCTION__, a_PlayerUUID.c_str(), a_RankName.c_str() + ); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to set player UUID %s to rank %s: %s", + __FUNCTION__, a_PlayerUUID.c_str(), a_RankName.c_str(), ex.what() + ); + } +} + + + + + +void cRankManager::SetRankVisuals( + const AString & a_RankName, + const AString & a_MsgPrefix, + const AString & a_MsgSuffix, + const AString & a_MsgNameColorCode +) +{ + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + +bool cRankManager::RankExists(const AString & a_RankName) +{ + try + { + SQLite::Statement stmt(m_DB, "SELECT * FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (stmt.executeStep()) + { + // The rank was found + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB for rank %s: %s", __FUNCTION__, a_RankName.c_str(), ex.what()); + } + return false; +} + + + + + +bool cRankManager::GroupExists(const AString & a_GroupName) +{ + try + { + SQLite::Statement stmt(m_DB, "SELECT * FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (stmt.executeStep()) + { + // The group was found + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB for group %s: %s", __FUNCTION__, a_GroupName.c_str(), ex.what()); + } + return false; +} + + + + + +bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) +{ + try + { + SQLite::Statement stmt(m_DB, "SELECT * FROM PlayerRank WHERE PlayerUUID = ?"); + stmt.bind(1, a_PlayerUUID); + if (stmt.executeStep()) + { + // The player UUID was found, they have a rank + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB for player UUID %s: %s", __FUNCTION__, a_PlayerUUID.c_str(), ex.what()); + } + return false; +} + + + + + +bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_RankName) +{ + try + { + SQLite::Statement stmt(m_DB, + "SELECT * FROM Rank " + "LEFT JOIN RankPermGroup ON Rank.RankID = RankPermGroup.RankID " + "LEFT JOIN PermGroup ON PermGroup.PermGroupID = RankPermGroup.PermGroupID " + "WHERE Rank.Name = ? AND PermGroup.Name = ?" + ); + stmt.bind(1, a_RankName); + stmt.bind(2, a_GroupName); + if (stmt.executeStep()) + { + // The group is in the rank + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + + +bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName) +{ + try + { + SQLite::Statement stmt(m_DB, + "SELECT * FROM PermissionItem " + "LEFT JOIN PermGroup ON PermGroup.PermGroupID = PermissionItem.PermGroupID " + "WHERE PermissionItem.Permission = ? AND PermGroup.Name = ?" + ); + stmt.bind(1, a_Permission); + stmt.bind(2, a_GroupName); + if (stmt.executeStep()) + { + // The permission is in the group + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + diff --git a/src/RankManager.h b/src/RankManager.h index 0b1db2fb8..0c35b555f 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -68,7 +68,7 @@ public: /** Adds the specified permission group to the specified rank. Fails if the rank or group names are not found. Returns true if successful, false on error. */ - bool AddGroupToRank(const AString & a_RankName, const AString & a_GroupName); + bool AddGroupToRank(const AString & a_GroupName, const AString & a_RankName); /** Adds the specified permission to the specified permission group. Fails if the permission group name is not found. @@ -113,6 +113,22 @@ public: const AString & a_MsgSuffix, const AString & a_MsgNameColorCode ); + + /** Returns true iff the specified rank exists in the DB. */ + bool RankExists(const AString & a_RankName); + + /** Returns true iff the specified group exists in the DB. */ + bool GroupExists(const AString & a_GroupName); + + /** Returns true iff the specified player has a rank assigned to them in the DB. */ + bool IsPlayerRankSet(const AString & a_PlayerUUID); + + /** Returns true iff the specified rank contains the specified group. */ + bool IsGroupInRank(const AString & a_GroupName, const AString & a_RankName); + + /** Returns true iff the specified group contains the specified permission. */ + bool IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName); + protected: SQLite::Database m_DB; -- cgit v1.2.3 From a5b35e09ce1e352d4c57e66750a72335fc60d4b2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 16:38:38 +0200 Subject: RankMgr: Implemented GetXforY and GetAll APIs. --- src/RankManager.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++++++----- src/RankManager.h | 9 ++- 2 files changed, 162 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index e02e63a24..ec9ac1b1d 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -11,7 +11,7 @@ -/* +//* // This code is for internal testing while developing the cRankManager class static class cRankMgrTest { @@ -53,6 +53,13 @@ public: LOG("GroupExists(TestGroup3) = %s", m_Mgr.GroupExists("TestGroup3") ? "true" : "false"); LOG("RankExists(TestRank) = %s", m_Mgr.RankExists("TestRank") ? "true" : "false"); LOG("RankExists(NonexistentRank) = %s", m_Mgr.RankExists("NonexistentRank") ? "true" : "false"); + ReportRankGroups("TestRank"); + ReportRankGroups("NonexistentRank"); + ReportGroupPermissions("TestGroup1"); + ReportGroupPermissions("NonexistentGroup"); + + // Report the contents of the DB: + ReportAll(); // Test the assignments above: LOG("After-assignment test:"); @@ -61,6 +68,35 @@ public: LOG("Done."); } + + void ReportAll(void) + { + // Report all ranks: + AStringVector Ranks = m_Mgr.GetAllRanks(); + LOG("All ranks (%u):", (unsigned)Ranks.size()); + for (AStringVector::const_iterator itr = Ranks.begin(), end = Ranks.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + + // Report all groups: + AStringVector Groups = m_Mgr.GetAllGroups(); + LOG("All groups (%u):", (unsigned)Groups.size()); + for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + + // Report all permissions: + AStringVector Permissions = m_Mgr.GetAllPermissions(); + LOG("All permissions (%u):", (unsigned)Permissions.size()); + for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + } + + void ReportPlayer(const AString & a_PlayerUUID) { // Get the player's UUID and rank: @@ -68,7 +104,7 @@ public: // List all the permission groups for the player: AStringVector Groups = m_Mgr.GetPlayerGroups(a_PlayerUUID); - LOG(" Groups(%u):", (unsigned)Groups.size()); + LOG(" Groups (%u):", (unsigned)Groups.size()); for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) { LOG(" '%s'" , itr->c_str()); @@ -76,13 +112,41 @@ public: // List all the permissions for the player: AStringVector Permissions = m_Mgr.GetPlayerPermissions(a_PlayerUUID); - LOG(" Permissions(%u):", (unsigned)Permissions.size()); + LOG(" Permissions (%u):", (unsigned)Permissions.size()); for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) { LOG(" '%s'", itr->c_str()); } // for itr - Groups[] } + + void ReportRankGroups(const AString & a_RankName) + { + AStringVector Groups = m_Mgr.GetRankGroups(a_RankName); + LOG("Groups in rank %s: %u", a_RankName.c_str(), (unsigned)Groups.size()); + for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + AStringVector Permissions = m_Mgr.GetRankPermissions(a_RankName); + LOG("Permissions in rank %s: %u", a_RankName.c_str(), (unsigned)Permissions.size()); + for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + } + + + void ReportGroupPermissions(const AString & a_GroupName) + { + AStringVector Permissions = m_Mgr.GetGroupPermissions(a_GroupName); + LOG("Permissions in group %s: %u", a_GroupName.c_str(), (unsigned)Permissions.size()); + for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) + { + LOG(" '%s'", itr->c_str()); + } + } + protected: cRankManager m_Mgr; } g_RankMgrTest; @@ -202,9 +266,25 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) AStringVector cRankManager::GetRankGroups(const AString & a_RankName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyGroup", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, + "SELECT PermGroup.Name FROM PermGroup " + "LEFT JOIN RankPermGroup ON RankPermGroup.PermGroupID = PermGroup.PermGroupID " + "LEFT JOIN Rank ON Rank.RankID = RankPermGroup.RankID " + "WHERE Rank.Name = ?" + ); + stmt.bind(1, a_RankName); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get rank groups from DB: %s", __FUNCTION__, ex.what()); + } return res; } @@ -214,9 +294,24 @@ AStringVector cRankManager::GetRankGroups(const AString & a_RankName) AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, + "SELECT PermissionItem.Permission FROM PermissionItem " + "LEFT JOIN PermGroup ON PermGroup.PermGroupID = PermissionItem.PermGroupID " + "WHERE PermGroup.Name = ?" + ); + stmt.bind(1, a_GroupName); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get group permissions from DB: %s", __FUNCTION__, ex.what()); + } return res; } @@ -226,9 +321,25 @@ AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, + "SELECT PermissionItem.Permission FROM PermissionItem " + "LEFT JOIN RankPermGroup ON RankPermGroup.PermGroupID = PermissionItem.PermGroupID " + "LEFT JOIN Rank ON Rank.RankID = RankPermGroup.RankID " + "WHERE Rank.Name = ?" + ); + stmt.bind(1, a_RankName); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get rank permissions from DB: %s", __FUNCTION__, ex.what()); + } return res; } @@ -238,9 +349,19 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) AStringVector cRankManager::GetAllRanks(void) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyRank", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, "SELECT Name FROM Rank"); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get ranks from DB: %s", __FUNCTION__, ex.what()); + } return res; } @@ -250,9 +371,19 @@ AStringVector cRankManager::GetAllRanks(void) AStringVector cRankManager::GetAllGroups(void) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyGroup", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, "SELECT Name FROM PermGroup"); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get groups from DB: %s", __FUNCTION__, ex.what()); + } return res; } @@ -262,9 +393,19 @@ AStringVector cRankManager::GetAllGroups(void) AStringVector cRankManager::GetAllPermissions(void) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); AStringVector res; - res.push_back(Printf("%s: DummyPermission", __FUNCTION__)); + try + { + SQLite::Statement stmt(m_DB, "SELECT Permission FROM PermissionItem"); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get permissions from DB: %s", __FUNCTION__, ex.what()); + } return res; } diff --git a/src/RankManager.h b/src/RankManager.h index 0c35b555f..9a1828275 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -28,13 +28,16 @@ public: /** Returns the permissions that the specified player has assigned to them. */ AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); - /** Returns the names of groups that the specified rank has assigned to it. */ + /** Returns the names of groups that the specified rank has assigned to it. + Returns an empty vector if the rank doesn't exist. */ AStringVector GetRankGroups(const AString & a_RankName); - /** Returns the permissions that the specified group has assigned to it. */ + /** Returns the permissions that the specified group has assigned to it. + Returns an empty vector if the group doesn't exist. */ AStringVector GetGroupPermissions(const AString & a_GroupName); - /** Returns all permissions that the specified rank has assigned to it, through all its groups. */ + /** Returns all permissions that the specified rank has assigned to it, through all its groups. + Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankPermissions(const AString & a_RankName); /** Returns the names of all defined ranks. */ -- cgit v1.2.3 From 3d68466ab03c3f7f2879451a57acba65ed5b197f Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 8 Aug 2014 18:55:05 +0200 Subject: Send the old slab to the client when the interact cancelled. --- src/Blocks/BlockSlab.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 214445eda..28fdbe7af 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -110,6 +110,17 @@ public: { return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB)); } + + + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + if ((a_BlockFace == BLOCK_FACE_NONE) || (a_Player->GetEquippedItem().m_ItemType != (short)m_BlockType)) + { + return; + } + + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } /// Converts the single-slab blocktype to its equivalent double-slab blocktype -- cgit v1.2.3 From 89333c5870efb438a38786fd67b82daff0482d9a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 21:30:47 +0200 Subject: RankMgr: Finished API implementation. --- src/RankManager.cpp | 421 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/RankManager.h | 18 ++- 2 files changed, 401 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index ec9ac1b1d..8a3b19c15 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -11,7 +11,7 @@ -//* +/* // This code is for internal testing while developing the cRankManager class static class cRankMgrTest { @@ -30,30 +30,35 @@ public: // Add a rank, a few groups and permissions and set the player to use them: LOG("Adding data..."); - m_Mgr.AddRank("TestRank", "[test]", "[/test]", "7"); + m_Mgr.AddRank("TestRank1", "[test]", "[/test]", "7"); + m_Mgr.AddRank("TestRank2", "[t2]", "[/t2]", "8"); m_Mgr.AddGroup("TestGroup1"); m_Mgr.AddGroup("TestGroup2"); - m_Mgr.AddGroupToRank("TestGroup1", "TestRank"); - m_Mgr.AddGroupToRank("TestGroup2", "TestRank"); + m_Mgr.AddGroupToRank("TestGroup1", "TestRank1"); + m_Mgr.AddGroupToRank("TestGroup2", "TestRank1"); + m_Mgr.AddGroupToRank("TestGroup2", "TestRank2"); m_Mgr.AddPermissionToGroup("testpermission1.1", "TestGroup1"); m_Mgr.AddPermissionToGroup("testpermission1.2", "TestGroup1"); + m_Mgr.AddPermissionToGroup("testpermission1.3", "TestGroup1"); + m_Mgr.AddPermissionToGroup("common", "TestGroup1"); m_Mgr.AddPermissionToGroup("testpermission2.1", "TestGroup2"); - m_Mgr.SetPlayerRank(UUID, "TestRank"); + m_Mgr.AddPermissionToGroup("common", "TestGroup2"); + m_Mgr.SetPlayerRank(UUID, "xoft", "TestRank1"); // Test the added data: LOG("Testing the added data:"); - LOG("IsGroupInRank(TestGroup1, TestRank) = %s", m_Mgr.IsGroupInRank("TestGroup1", "TestRank") ? "true" : "false"); - LOG("IsGroupInRank(TestGroup3, TestRank) = %s", m_Mgr.IsGroupInRank("TestGroup3", "TestRank") ? "true" : "false"); - LOG("IsPermissionInGroup(testpermission1.2, TestGroup1) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup1") ? "true" : "false"); - LOG("IsPermissionInGroup(testpermission1.2, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup2") ? "true" : "false"); - LOG("IsPermissionInGroup(testpermission1.3, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.3", "TestGroup2") ? "true" : "false"); + LOG("IsGroupInRank(TestGroup1, TestRank1) = %s", m_Mgr.IsGroupInRank("TestGroup1", "TestRank1") ? "true" : "false"); + LOG("IsGroupInRank(TestGroup3, TestRank1) = %s", m_Mgr.IsGroupInRank("TestGroup3", "TestRank1") ? "true" : "false"); + LOG("IsPermissionInGroup(testpermission1.2, TestGroup1) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup1") ? "true" : "false"); // Existing permission, in group + LOG("IsPermissionInGroup(testpermission1.2, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup2") ? "true" : "false"); // Existing permission, not in group + LOG("IsPermissionInGroup(testpermission1.9, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.9", "TestGroup2") ? "true" : "false"); // Non-existing permission LOG("IsPlayerRankSet(%s) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID) ? "true" : "false"); LOG("IsPlayerRankSet(%s1) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID + "1") ? "true" : "false"); LOG("GroupExists(TestGroup1) = %s", m_Mgr.GroupExists("TestGroup1") ? "true" : "false"); LOG("GroupExists(TestGroup3) = %s", m_Mgr.GroupExists("TestGroup3") ? "true" : "false"); - LOG("RankExists(TestRank) = %s", m_Mgr.RankExists("TestRank") ? "true" : "false"); + LOG("RankExists(TestRank1) = %s", m_Mgr.RankExists("TestRank1") ? "true" : "false"); LOG("RankExists(NonexistentRank) = %s", m_Mgr.RankExists("NonexistentRank") ? "true" : "false"); - ReportRankGroups("TestRank"); + ReportRankGroups("TestRank1"); ReportRankGroups("NonexistentRank"); ReportGroupPermissions("TestGroup1"); ReportGroupPermissions("NonexistentGroup"); @@ -64,7 +69,65 @@ public: // Test the assignments above: LOG("After-assignment test:"); ReportPlayer(UUID); + + // Test removing a permission from a group: + LOG("Removing permission testpermission1.3 from group TestGroup1."); + m_Mgr.RemovePermissionFromGroup("testpermission1.3", "TestGroup1"); + ReportGroupPermissions("TestGroup1"); + LOG("Removing permission common from group TestGroup1."); + m_Mgr.RemovePermissionFromGroup("common", "TestGroup1"); + ReportGroupPermissions("TestGroup1"); // Check that it's not present + ReportGroupPermissions("TestGroup2"); // Check that it's still present here + + // Test removing a group from rank: + LOG("Removing group TestGroup2 from rank TestRank1."); + m_Mgr.RemoveGroupFromRank("TestGroup2", "TestRank1"); + ReportRankGroups("TestRank1"); + LOG("Removing group TestGroup3 from rank TestRank1."); + m_Mgr.RemoveGroupFromRank("TestGroup3", "TestRank1"); + ReportRankGroups("TestRank1"); + + // Test re-adding the groups: + LOG("Re-adding groups to TestRank1."); + m_Mgr.AddGroupToRank("TestGroup1", "TestRank1"); + m_Mgr.AddGroupToRank("TestGroup2", "TestRank1"); + ReportRankGroups("TestRank1"); + + // Test removing a group altogether: + LOG("Removing group TestGroup2"); + m_Mgr.RemoveGroup("TestGroup2"); + ReportAll(); + + // Test removing a rank: + LOG("Removing rank TestRank2, replacing with rank TestRank1."); + m_Mgr.RemoveRank("TestRank2", "TestRank1"); + ReportAll(); + LOG("Removing rank Test altogether."); + m_Mgr.RemoveRank("Test", ""); + ReportAll(); + + // Test renaming a rank: + LOG("Renaming rank TestRank1 to Test"); + m_Mgr.RenameRank("TestRank1", "Test"); + ReportRankGroups("TestRank1"); + ReportRankGroups("Test"); + LOG("Player after renaming:"); + ReportPlayer(UUID); + + // Test renaming a group: + LOG("Renaming group TestGroup1 to Test"); + m_Mgr.RenameGroup("TestGroup1", "Test"); + ReportGroupPermissions("TestGroup1"); + ReportGroupPermissions("Test"); + LOG("Player after renaming:"); + ReportPlayer(UUID); + m_Mgr.RenameGroup("Test", "TestGroup1"); + // Test removing the rank in favor of another one: + m_Mgr.RemoveRank("Test", "TestRank2"); + LOG("After-removal test:"); + ReportPlayer(UUID); + LOG("Done."); } @@ -238,7 +301,7 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) { // Prepare the DB statement: SQLite::Statement stmt(m_DB, - "SELECT PermissionItem.Permission FROM PermissionItem " + "SELECT DISTINCT(PermissionItem.Permission) FROM PermissionItem " "LEFT JOIN RankPermGroup " "ON PermissionItem.PermGroupID = RankPermGroup.PermGroupID " "LEFT JOIN PlayerRank " @@ -396,7 +459,7 @@ AStringVector cRankManager::GetAllPermissions(void) AStringVector res; try { - SQLite::Statement stmt(m_DB, "SELECT Permission FROM PermissionItem"); + SQLite::Statement stmt(m_DB, "SELECT DISTINCT(Permission) FROM PermissionItem"); while (stmt.executeStep()) { res.push_back(stmt.getColumn(0).getText()); @@ -413,17 +476,43 @@ AStringVector cRankManager::GetAllPermissions(void) -void cRankManager::GetPlayerMsgVisuals( +bool cRankManager::GetPlayerMsgVisuals( const AString & a_PlayerUUID, AString & a_MsgPrefix, AString & a_MsgSuffix, AString & a_MsgNameColorCode ) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); - a_MsgPrefix = Printf("%s: DummyPrefix", __FUNCTION__); - a_MsgSuffix = Printf("%s: DummySuffix", __FUNCTION__); - a_MsgNameColorCode = Printf("%s: DummyMsgNameColorCode", __FUNCTION__); + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, + "SELECT Rank.MsgPrefix, Rank.MsgSuffix, Rank.MsgNameColorCode FROM Rank " + "LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID " + "WHERE PlayerRank.PlayerUUID = ?" + ); + stmt.bind(1, a_PlayerUUID); + if (!stmt.executeStep()) + { + LOGD("%s: Player UUID %s not found in the DB, returning empty values.", __FUNCTION__, a_PlayerUUID.c_str()); + a_MsgPrefix.clear(); + a_MsgSuffix.clear(); + a_MsgNameColorCode.clear(); + return false; + } + a_MsgPrefix = stmt.getColumn(0).getText(); + a_MsgSuffix = stmt.getColumn(1).getText(); + a_MsgNameColorCode = stmt.getColumn(2).getText(); + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get ranks from DB: %s. Returning empty values.", __FUNCTION__, ex.what()); + } + a_MsgPrefix.clear(); + a_MsgSuffix.clear(); + a_MsgNameColorCode.clear(); + return false; } @@ -659,7 +748,73 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the RankID for the rank being removed: + int RemoveRankID; + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Rank %s was not found. Skipping.", __FUNCTION__, a_RankName.c_str()); + return; + } + RemoveRankID = stmt.getColumn(0).getInt(); + } + + // Get the RankID for the replacement rank: + int ReplacementRankID = -1; + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_ReplacementRankName); + if (stmt.executeStep()) + { + ReplacementRankID = stmt.getColumn(0).getInt(); + } + } + + // Remove the rank's bindings to groups: + { + SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE RankID = ?"); + stmt.bind(1, RemoveRankID); + stmt.exec(); + } + + // Adjust players: + if (ReplacementRankID == -1) + { + // No replacement, just delete all the players that have the rank: + SQLite::Statement stmt(m_DB, "DELETE FROM PlayerRank WHERE RankID = ?"); + stmt.bind(1, RemoveRankID); + stmt.exec(); + } + else + { + // Replacement available, change all the player records: + SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ? WHERE RankID = ?"); + stmt.bind(1, ReplacementRankID); + stmt.bind(2, RemoveRankID); + stmt.exec(); + } + + // Remove the rank from the DB: + { + SQLite::Statement stmt(m_DB, "DELETE FROM Rank WHERE RankID = ?"); + stmt.bind(1, RemoveRankID); + stmt.exec(); + } + + trans.commit(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove rank from DB: %s", __FUNCTION__, ex.what()); + } } @@ -668,16 +823,105 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl void cRankManager::RemoveGroup(const AString & a_GroupName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the ID of the group: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Group %s was not found, skipping.", __FUNCTION__, a_GroupName.c_str()); + return; + } + GroupID = stmt.getColumn(0).getInt(); + } + + // Remove all permissions from the group: + { + SQLite::Statement stmt(m_DB, "DELETE FROM PermissionItem WHERE PermGroupID = ?"); + stmt.bind(1, GroupID); + stmt.exec(); + } + + // Remove the group from all ranks that contain it: + { + SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ?"); + stmt.bind(1, GroupID); + stmt.exec(); + } + + // Remove the group itself: + { + SQLite::Statement stmt(m_DB, "DELETE FROM PermGroup WHERE PermGroupID = ?"); + stmt.bind(1, GroupID); + stmt.exec(); + } + + trans.commit(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove group %s from DB: %s", __FUNCTION__, a_GroupName.c_str(), ex.what()); + } } -void cRankManager::RemoveGroupFromRank(const AString & a_RankName, const AString & a_GroupName) +void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AString & a_RankName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the IDs of the group and the rank: + int GroupID, RankID; + { + SQLite::Statement stmt(m_DB, + "SELECT PermGroup.PermGroupID, Rank.RankID FROM PermGroup " + "LEFT JOIN RankPermGroup ON RankPermGroup.PermGroupID = PermGroup.PermGroupID " + "LEFT JOIN Rank ON Rank.RankID = RankPermGroup.RankID " + "WHERE PermGroup.Name = ? AND Rank.Name = ?" + ); + stmt.bind(1, a_GroupName); + stmt.bind(2, a_RankName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Group %s was not found in rank %s, skipping.", __FUNCTION__, a_GroupName.c_str(), a_RankName.c_str()); + return; + } + GroupID = stmt.getColumn(0).getInt(); + RankID = stmt.getColumn(1).getInt(); + } + + // Remove the group from all ranks that contain it: + { + SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ?"); + stmt.bind(1, GroupID); + stmt.exec(); + } + + // Remove the group-to-rank binding: + { + SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ? AND RankID = ?"); + stmt.bind(1, GroupID); + stmt.bind(1, RankID); + stmt.exec(); + } + + trans.commit(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove group %s from rank %s in the DB: %s", __FUNCTION__, a_GroupName.c_str(), a_RankName.c_str(), ex.what()); + } } @@ -686,7 +930,40 @@ void cRankManager::RemoveGroupFromRank(const AString & a_RankName, const AString void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the ID of the group: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Group %s was not found, skipping.", __FUNCTION__, a_GroupName.c_str()); + return; + } + GroupID = stmt.getColumn(0).getInt(); + } + + // Remove the permission from the group: + { + SQLite::Statement stmt(m_DB, "DELETE FROM PermissionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, a_Permission); + stmt.exec(); + } + + trans.commit(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove permission %s from group %s in DB: %s", + __FUNCTION__, a_Permission.c_str(), a_GroupName.c_str(), ex.what() + ); + } } @@ -695,7 +972,39 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Check that NewName doesn't exist: + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_NewName); + if (stmt.executeStep()) + { + LOGD("%s: Rank %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str()); + return false; + } + } + + // Rename: + bool res; + { + SQLite::Statement stmt(m_DB, "UPDATE Rank SET Name = ? WHERE Name = ?"); + stmt.bind(1, a_NewName); + stmt.bind(2, a_OldName); + res = (stmt.exec() > 0); + } + + trans.commit(); + return res; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to rename rank %s to %s in DB: %s", + __FUNCTION__, a_OldName.c_str(), a_NewName.c_str(), ex.what()); + } return false; } @@ -705,7 +1014,39 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewName) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + try + { + // Wrap everything into a transaction: + SQLite::Transaction trans(m_DB); + + // Check that NewName doesn't exist: + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_NewName); + if (stmt.executeStep()) + { + LOGD("%s: Group %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str()); + return false; + } + } + + // Rename: + bool res; + { + SQLite::Statement stmt(m_DB, "UPDATE PermGroup SET Name = ? WHERE Name = ?"); + stmt.bind(1, a_NewName); + stmt.bind(2, a_OldName); + res = (stmt.exec() > 0); + } + + trans.commit(); + return res; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to rename group %s to %s in DB: %s", + __FUNCTION__, a_OldName.c_str(), a_NewName.c_str(), ex.what()); + } return false; } @@ -713,7 +1054,7 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN -void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_RankName) +void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName) { try { @@ -735,9 +1076,10 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a // Update the player's rank, if already in DB: { - SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ? WHERE PlayerUUID = ?"); + SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ?, PlayerName = ? WHERE PlayerUUID = ?"); stmt.bind(1, RankID); - stmt.bind(2, a_PlayerUUID); + stmt.bind(2, a_PlayerName); + stmt.bind(3, a_PlayerUUID); if (stmt.exec() > 0) { // Successfully updated the player's rank @@ -747,9 +1089,10 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a } // The player is not yet in the DB, add them: - SQLite::Statement stmt(m_DB, "INSERT INTO PlayerRank (RankID, PlayerUUID) VALUES (?, ?)"); + SQLite::Statement stmt(m_DB, "INSERT INTO PlayerRank (RankID, PlayerUUID, PlayerName) VALUES (?, ?, ?)"); stmt.bind(1, RankID); stmt.bind(2, a_PlayerUUID); + stmt.bind(3, a_PlayerName); if (stmt.exec() > 0) { // Successfully added the player @@ -780,7 +1123,23 @@ void cRankManager::SetRankVisuals( const AString & a_MsgNameColorCode ) { - LOGWARNING("%s: Not implemented yet", __FUNCTION__); + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, "UPDATE Rank SET MsgPrefix = ?, MsgSuffix = ?, MsgNameColorCode = ? WHERE Name = ?"); + stmt.bind(1, a_MsgPrefix); + stmt.bind(2, a_MsgSuffix); + stmt.bind(1, a_MsgNameColorCode); + stmt.bind(2, a_RankName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Rank %s not found, visuals not set.", __FUNCTION__, a_RankName.c_str()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get ranks from DB: %s", __FUNCTION__, ex.what()); + } } diff --git a/src/RankManager.h b/src/RankManager.h index 9a1828275..e13febdac 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -49,8 +49,9 @@ public: /** Returns all the distinct permissions that are stored in the DB. */ AStringVector GetAllPermissions(void); - /** Returns the message visuals (prefix, postfix, color) for the specified player. */ - void GetPlayerMsgVisuals( + /** Returns the message visuals (prefix, postfix, color) for the specified player. + Returns true if the visuals were read from the DB, false if not (player not found etc). */ + bool GetPlayerMsgVisuals( const AString & a_PlayerUUID, AString & a_MsgPrefix, AString & a_MsgSuffix, @@ -79,7 +80,9 @@ public: bool AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName); /** Removes the specified rank. - All players assigned to that rank will be re-assigned to a_ReplacementRankName, unless it is empty. */ + All players assigned to that rank will be re-assigned to a_ReplacementRankName. + If a_ReplacementRankName is empty or not a valid rank, the player will be removed from the DB, + which means they will receive the default rank the next time they are queried. */ void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); /** Removes the specified group completely. @@ -88,7 +91,7 @@ public: /** Removes the specified group from the specified rank. The group will stay defined, even if no rank is using it. */ - void RemoveGroupFromRank(const AString & a_RankName, const AString & a_GroupName); + void RemoveGroupFromRank(const AString & a_GroupName, const AString & a_RankName); /** Removes the specified permission from the specified group. */ void RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName); @@ -104,10 +107,11 @@ public: bool RenameGroup(const AString & a_OldName, const AString & a_NewName); /** Sets the specified player's rank. - If the player already had rank assigned to them, it is overwritten with the new rank. + If the player already had rank assigned to them, it is overwritten with the new rank and name. Note that this doesn't change the cPlayer if the player is already connected, you need to update all the - cPlayer instances manually. */ - void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_RankName); + cPlayer instances manually. + The PlayerName is provided for reference, so that GetRankPlayerNames() can work. */ + void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName); /** Sets the message visuals of an existing rank. No action if the rank name is not found. */ void SetRankVisuals( -- cgit v1.2.3 From ebfc0fdc676eb4e0e99fc59ab6da6919fa2ef471 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 8 Aug 2014 22:04:53 +0200 Subject: Added comment. --- src/Blocks/BlockSlab.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 28fdbe7af..49f00c88c 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -119,6 +119,9 @@ public: return; } + /* Sends the slab back to the client. + The normal back sending adds the block face to the locations, but this don't work because the Y-Coordinate with the block face + is one higher than the real slab position. */ a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } -- cgit v1.2.3 From 32e1e9a5536f92d074d51cca207f21c372973629 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 8 Aug 2014 18:38:20 +0200 Subject: Renamed m_DoDaylightCycle to m_CycleDaylight. --- src/World.cpp | 6 +++--- src/World.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 7ed8bc1e4..ab46e886c 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -243,7 +243,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin #endif m_Dimension(a_Dimension), m_IsSpawnExplicitlySet(false), - m_DoDaylightCycle(true), + m_CycleDaylight(true), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -832,7 +832,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_WorldAgeSecs += (double)a_Dt / 1000.0; m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - if (m_DoDaylightCycle) + if (m_CycleDaylight) { // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it m_TimeOfDaySecs += (double)a_Dt / 1000.0; @@ -2249,7 +2249,7 @@ void cWorld::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { int TimeOfDay = m_TimeOfDay; - if (!m_DoDaylightCycle) + if (!m_CycleDaylight) { TimeOfDay *= -1; if (TimeOfDay == 0) diff --git a/src/World.h b/src/World.h index 8ddc69118..4e85087fc 100644 --- a/src/World.h +++ b/src/World.h @@ -147,12 +147,12 @@ public: int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } /** Is the daylight cyclus enabled? */ - virtual bool IsDaylightCycleEnabled(void) const { return m_DoDaylightCycle; } + virtual bool IsDaylightCycleEnabled(void) const { return m_CycleDaylight; } /** Sets the daylight cyclus to true/false. */ - virtual void SetDoDaylightCycle(bool a_DoDaylightCycle) + virtual void SetDoDaylightCycle(bool a_CycleDaylight) { - m_DoDaylightCycle = a_DoDaylightCycle; + m_CycleDaylight = a_CycleDaylight; BroadcastTimeUpdate(); } @@ -879,7 +879,7 @@ private: bool m_BroadcastDeathMessages; bool m_BroadcastAchievementMessages; - bool m_DoDaylightCycle; // Is the daylight cyclus enabled? + bool m_CycleDaylight; // Is the daylight cyclus enabled? double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs -- cgit v1.2.3 From 3df7d8446c4d5387475a8d6c2f1c3d5ab28b28eb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 23:11:42 +0200 Subject: cLuaState: Added GetStackValues() auto-generated templates. These will read consecutive values off the stack, each value of a type independent of the other values. Auto-generated because we don't have variadic templates in C++03. --- src/Bindings/gen_LuaState_Call.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index 17bae82b3..a5d09d4f1 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -182,6 +182,33 @@ for _, combination in ipairs(Combinations) do WriteOverload(f, combination[1], combination[2]) end +-- Generate the cLuaState::GetStackValues() multi-param templates: +for i = 2, 6 do + f:write("/** Reads ", i, " consecutive values off the stack */\ntemplate <\n") + + -- Write the template function header: + local txt = {} + for idx = 1, i do + table.insert(txt, "\ttypename ArgT" .. idx) + end + f:write(table.concat(txt, ",\n")) + + -- Write the argument declarations: + txt = {} + f:write("\n>\nvoid GetStackValues(\n\tint a_BeginPos,\n") + for idx = 1, i do + table.insert(txt, "\tArgT" .. idx .. " & Arg" .. idx) + end + f:write(table.concat(txt, ",\n")) + + -- Write the function body: + f:write("\n)\n{\n") + for idx = 1, i do + f:write("\tGetStackValue(a_BeginPos + ", idx - 1, ", Arg", idx, ");\n") + end + f:write("}\n\n\n\n\n\n") +end + -- Close the generated file f:close() -- cgit v1.2.3 From f1dc299fdb6d2460437608ce79da4db9d0bde7f1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 8 Aug 2014 23:12:22 +0200 Subject: Exported cRankManager to LuaAPI. --- src/Bindings/CMakeLists.txt | 1 + src/Bindings/ManualBindings.cpp | 2 + src/Bindings/ManualBindings.h | 19 +- src/Bindings/ManualBindings_RankManager.cpp | 870 ++++++++++++++++++++++++++++ src/Root.h | 3 + 5 files changed, 894 insertions(+), 1 deletion(-) create mode 100644 src/Bindings/ManualBindings_RankManager.cpp (limited to 'src') diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index a2b381a26..4b8df52f6 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -11,6 +11,7 @@ SET (SRCS LuaState.cpp LuaWindow.cpp ManualBindings.cpp + ManualBindings_RankManager.cpp Plugin.cpp PluginLua.cpp PluginManager.cpp diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 042ffb19e..5563fb14a 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3262,6 +3262,8 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_function(tolua_S, "md5", tolua_md5); + + BindRankManager(tolua_S); tolua_endmodule(tolua_S); } diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index 36161c6a2..0302b9503 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -1,8 +1,25 @@ #pragma once struct lua_State; + + + + + + +/** Provides namespace for the bindings. */ class ManualBindings { public: - static void Bind( lua_State* tolua_S); + /** Binds all the manually implemented functions to tolua_S. */ + static void Bind(lua_State * tolua_S); + +protected: + /** Binds the manually implemented cRankManager glue code to tolua_S. + Implemented in ManualBindings_RankManager.cpp. */ + static void BindRankManager(lua_State * tolua_S); }; + + + + diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp new file mode 100644 index 000000000..daa810cd4 --- /dev/null +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -0,0 +1,870 @@ + +// ManualBindings_RankManager.cpp + +// Implements the cRankManager Lua bindings + +#include "Globals.h" +#include "ManualBindings.h" +#include "../Root.h" +#include "tolua++/include/tolua++.h" +#include "LuaState.h" + + + + + +/** Binds cRankManager::AddGroup */ +static int tolua_cRankManager_AddGroup(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Read the params: + AString GroupName; + S.GetStackValue(2, GroupName); + + // Add the group: + cRoot::Get()->GetRankManager().AddGroup(GroupName); + return 0; +} + + + + + +/** Binds cRankManager::AddGroup */ +static int tolua_cRankManager_AddGroupToRank(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Read the params: + AString GroupName, RankName; + S.GetStackValues(2, GroupName, RankName); + + // Add the group to the rank: + cRoot::Get()->GetRankManager().AddGroupToRank(GroupName, RankName); + return 0; +} + + + + + +/** Binds cRankManager::AddPermissionToGroup */ +static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Read the params: + AString GroupName, Permission; + S.GetStackValues(2, Permission, GroupName); + + // Add the group to the rank: + cRoot::Get()->GetRankManager().AddPermissionToGroup(Permission, GroupName); + return 0; +} + + + + + +/** Binds cRankManager::AddRank */ +static int tolua_cRankManager_AddRank(lua_State * L) +{ + // function signature: + // cRankManager:AddRank(RankName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Read the params: + AString RankName, MsgPrefix, MsgSuffix, MsgNameColorCode; + S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + + // Add the rank: + cRoot::Get()->GetRankManager().AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + return 0; +} + + + + + +/** Binds cRankManager::GetAllGroups */ +static int tolua_cRankManager_GetAllGroups(lua_State * L) +{ + // function signature: + // cRankManager:GetAllGroups() -> arraytable of GroupNames + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the groups: + AStringVector Groups = cRoot::Get()->GetRankManager().GetAllGroups(); + + // Push the results: + S.Push(Groups); + return 1; +} + + + + + +/** Binds cRankManager::GetAllPermissions */ +static int tolua_cRankManager_GetAllPermissions(lua_State * L) +{ + // function signature: + // cRankManager:GetAllPermissions() -> arraytable of Permissions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager().GetAllPermissions(); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + +/** Binds cRankManager::GetAllRanks */ +static int tolua_cRankManager_GetAllRanks(lua_State * L) +{ + // function signature: + // cRankManager:GetAllRanks() -> arraytable of RankNames + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the ranks: + AStringVector Ranks = cRoot::Get()->GetRankManager().GetAllRanks(); + + // Push the results: + S.Push(Ranks); + return 1; +} + + + + + +/** Binds cRankManager::GetGroupPermissions */ +static int tolua_cRankManager_GetGroupPermissions(lua_State * L) +{ + // function signature: + // cRankManager:GetGroupPermissions(GroupName) -> arraytable of permissions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString GroupName; + S.GetStackValue(2, GroupName); + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager().GetGroupPermissions(GroupName); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + +/** Binds cRankManager::GetPlayerGroups */ +static int tolua_cRankManager_GetPlayerGroups(lua_State * L) +{ + // function signature: + // cRankManager:GetPlayerGroups(PlayerUUID) -> arraytable of GroupNames + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the groups: + AStringVector Groups = cRoot::Get()->GetRankManager().GetPlayerGroups(PlayerUUID); + + // Push the results: + S.Push(Groups); + return 1; +} + + + + + +/** Binds cRankManager::GetPlayerMsgVisuals */ +static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) +{ + // function signature: + // cRankManager:GetPlayerMsgVisuals(PlayerUUID) -> string, string, string + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the permissions: + AString MsgPrefix, MsgSuffix, MsgNameColorCode; + cRoot::Get()->GetRankManager().GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode); + + // Push the results: + S.Push(MsgPrefix); + S.Push(MsgSuffix); + S.Push(MsgNameColorCode); + return 3; +} + + + + + +/** Binds cRankManager::GetPlayerPermissions */ +static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) +{ + // function signature: + // cRankManager:GetPlayerPermissions(PlayerUUID) -> arraytable of permissions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager().GetPlayerPermissions(PlayerUUID); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + +/** Binds cRankManager::GetPlayerRankName */ +static int tolua_cRankManager_GetPlayerRankName(lua_State * L) +{ + // function signature: + // cRankManager:GetPlayerRankName(PlayerUUID) -> string + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the rank name: + AString RankName = cRoot::Get()->GetRankManager().GetPlayerRankName(PlayerUUID); + + // Push the result: + S.Push(RankName); + return 1; +} + + + + + +/** Binds cRankManager::GetRankGroups */ +static int tolua_cRankManager_GetRankGroups(lua_State * L) +{ + // function signature: + // cRankManager:GetRankGroups(RankName) -> arraytable of groupnames + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Get the groups: + AStringVector Groups = cRoot::Get()->GetRankManager().GetRankGroups(RankName); + + // Push the results: + S.Push(Groups); + return 1; +} + + + + + +/** Binds cRankManager::GetRankPermissions */ +static int tolua_cRankManager_GetRankPermissions(lua_State * L) +{ + // function signature: + // cRankManager:GetRankPermissions(RankName) -> arraytable of permissions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager().GetRankPermissions(RankName); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + +/** Binds cRankManager::GroupExists */ +static int tolua_cRankManager_GroupExists(lua_State * L) +{ + // function signature: + // cRankManager:GroupExists(GroupName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString GroupName; + S.GetStackValue(2, GroupName); + + // Get the response: + bool res = cRoot::Get()->GetRankManager().GroupExists(GroupName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::IsGroupInRank */ +static int tolua_cRankManager_IsGroupInRank(lua_State * L) +{ + // function signature: + // cRankManager:IsGroupInRank(GroupName, RankName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, RankName; + S.GetStackValues(2, GroupName, RankName); + + // Get the response: + bool res = cRoot::Get()->GetRankManager().IsGroupInRank(GroupName, RankName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::IsPermissionInGroup */ +static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) +{ + // function signature: + // cRankManager:IsPermissionInGroup(Permission, GroupName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, Permission; + S.GetStackValues(2, Permission, GroupName); + + // Get the response: + bool res = cRoot::Get()->GetRankManager().IsPermissionInGroup(Permission, GroupName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::IsPlayerRankSet */ +static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) +{ + // function signature: + // cRankManager:IsPlayerRankSet(PlayerUUID) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the response: + bool res = cRoot::Get()->GetRankManager().IsPlayerRankSet(PlayerUUID); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::RankExists */ +static int tolua_cRankManager_RankExists(lua_State * L) +{ + // function signature: + // cRankManager:RankExists(RankName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Get the response: + bool res = cRoot::Get()->GetRankManager().RankExists(RankName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::RemoveGroup */ +static int tolua_cRankManager_RemoveGroup(lua_State * L) +{ + // function signature: + // cRankManager:RemoveGroup(GroupName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString GroupName; + S.GetStackValue(2, GroupName); + + // Remove the group: + cRoot::Get()->GetRankManager().RemoveGroup(GroupName); + return 0; +} + + + + + +/** Binds cRankManager::RemoveGroupFromRank */ +static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) +{ + // function signature: + // cRankManager:RemoveGroupFromRank(GroupName, RankName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, RankName; + S.GetStackValues(2, GroupName, RankName); + + // Remove the group: + cRoot::Get()->GetRankManager().RemoveGroupFromRank(GroupName, RankName); + return 0; +} + + + + + +/** Binds cRankManager::RemovePermissionFromGroup */ +static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) +{ + // function signature: + // cRankManager:RemovePermissionFromGroup(Permission, GroupName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, Permission; + S.GetStackValues(2, Permission, GroupName); + + // Remove the group: + cRoot::Get()->GetRankManager().RemovePermissionFromGroup(Permission, GroupName); + return 0; +} + + + + + +/** Binds cRankManager::RemoveRank */ +static int tolua_cRankManager_RemoveRank(lua_State * L) +{ + // function signature: + // cRankManager:RemoveRank(RankName, [ReplacementRankName]) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + // Param 3 is otpional, defaults to nil -> empty string + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString RankName, ReplacementRankName; + S.GetStackValues(2, RankName, ReplacementRankName); + + // Remove the rank: + cRoot::Get()->GetRankManager().RemoveRank(RankName, ReplacementRankName); + return 0; +} + + + + + +/** Binds cRankManager::RenameGroup */ +static int tolua_cRankManager_RenameGroup(lua_State * L) +{ + // function signature: + // cRankManager:RenameGroup(OldName, NewName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString OldName, NewName; + S.GetStackValues(2, OldName, NewName); + + // Remove the group: + bool res = cRoot::Get()->GetRankManager().RenameGroup(OldName, NewName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::RenameRank */ +static int tolua_cRankManager_RenameRank(lua_State * L) +{ + // function signature: + // cRankManager:RenameRank(OldName, NewName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString OldName, NewName; + S.GetStackValues(2, OldName, NewName); + + // Remove the rank: + bool res = cRoot::Get()->GetRankManager().RenameRank(OldName, NewName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + +/** Binds cRankManager::SetPlayerRank */ +static int tolua_cRankManager_SetPlayerRank(lua_State * L) +{ + // function signature: + // cRankManager:SetPlayerRank(PlayerUUID, PlayerName, RankName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 4) || + !S.CheckParamEnd(5) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID, PlayerName, RankName; + S.GetStackValues(2, PlayerUUID, PlayerName, RankName); + + // Set the rank: + cRoot::Get()->GetRankManager().SetPlayerRank(PlayerUUID, PlayerName, RankName); + return 0; +} + + + + + +/** Binds cRankManager::SetRankVisuals */ +static int tolua_cRankManager_SetRankVisuals(lua_State * L) +{ + // function signature: + // cRankManager:SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 5) || + !S.CheckParamEnd(6) + ) + { + return 0; + } + + // Get the params: + AString RankName, MsgPrefix, MsgSuffix, MsgNameColorCode; + S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + + // Set the visuals: + cRoot::Get()->GetRankManager().SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + return 0; +} + + + + + +void ManualBindings::BindRankManager(lua_State * tolua_S) +{ + // Create the cRankManager class in the API: + tolua_usertype(tolua_S, "cRankManager"); + tolua_cclass(tolua_S, "cRankManager", "cRankManager", "", NULL); + + // Fill in the functions (alpha-sorted): + tolua_beginmodule(tolua_S, "cRankManager"); + tolua_function(tolua_S, "AddGroup", tolua_cRankManager_AddGroup); + tolua_function(tolua_S, "AddGroupToRank", tolua_cRankManager_AddGroupToRank); + tolua_function(tolua_S, "AddPermissionToGroup", tolua_cRankManager_AddPermissionToGroup); + tolua_function(tolua_S, "AddRank", tolua_cRankManager_AddRank); + tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); + tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); + tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); + tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); + tolua_function(tolua_S, "GetPlayerGroups", tolua_cRankManager_GetPlayerGroups); + tolua_function(tolua_S, "GetPlayerMsgVisuals", tolua_cRankManager_GetPlayerMsgVisuals); + tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); + tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); + tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); + tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); + tolua_function(tolua_S, "GroupExists", tolua_cRankManager_GroupExists); + tolua_function(tolua_S, "IsGroupInRank", tolua_cRankManager_IsGroupInRank); + tolua_function(tolua_S, "IsPermissionInGroup", tolua_cRankManager_IsPermissionInGroup); + tolua_function(tolua_S, "IsPlayerRankSet", tolua_cRankManager_IsPlayerRankSet); + tolua_function(tolua_S, "RankExists", tolua_cRankManager_RankExists); + tolua_function(tolua_S, "RemoveGroup", tolua_cRankManager_RemoveGroup); + tolua_function(tolua_S, "RemoveGroupFromRank", tolua_cRankManager_RemoveGroupFromRank); + tolua_function(tolua_S, "RemovePermissionFromGroup", tolua_cRankManager_RemovePermissionFromGroup); + tolua_function(tolua_S, "RemoveRank", tolua_cRankManager_RemoveRank); + tolua_function(tolua_S, "RenameGroup", tolua_cRankManager_RenameGroup); + tolua_function(tolua_S, "RenameRank", tolua_cRankManager_RenameRank); + tolua_function(tolua_S, "SetPlayerRank", tolua_cRankManager_SetPlayerRank); + tolua_function(tolua_S, "SetRankVisuals", tolua_cRankManager_SetRankVisuals); + tolua_endmodule(tolua_S); +} + + + + diff --git a/src/Root.h b/src/Root.h index 1cd175ab4..68469c72f 100644 --- a/src/Root.h +++ b/src/Root.h @@ -5,6 +5,7 @@ #include "Protocol/MojangAPI.h" #include "HTTPServer/HTTPServer.h" #include "Defines.h" +#include "RankManager.h" @@ -89,6 +90,7 @@ public: cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export cAuthenticator & GetAuthenticator (void) { return m_Authenticator; } cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; } + cRankManager & GetRankManager (void) { return m_RankManager; } /** Queues a console command for execution through the cServer class. The command will be executed in the tick thread @@ -194,6 +196,7 @@ private: cPluginManager * m_PluginManager; cAuthenticator m_Authenticator; cMojangAPI m_MojangAPI; + cRankManager m_RankManager; cHTTPServer m_HTTPServer; cMCLogger * m_Log; -- cgit v1.2.3 From 0001a7c9fc2359078968565a8ab464509362b776 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 9 Aug 2014 17:36:19 +0200 Subject: RankMgr: Added GetRankVisuals() function. --- src/Bindings/ManualBindings_RankManager.cpp | 40 +++++++++++++++++++++++++++-- src/RankManager.cpp | 37 +++++++++++++++++++++++--- src/RankManager.h | 9 +++++++ 3 files changed, 81 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index daa810cd4..d17672dcb 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -100,8 +100,8 @@ static int tolua_cRankManager_AddRank(lua_State * L) cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || - !S.CheckParamString(2) || - !S.CheckParamEnd(3) + !S.CheckParamString(2, 5) || + !S.CheckParamEnd(6) ) { return 0; @@ -396,6 +396,41 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) +/** Binds cRankManager::GetRankVisuals */ +static int tolua_cRankManager_GetRankVisuals(lua_State * L) +{ + // function signature: + // cRankManager:GetRankVisuals(RankName) -> MsgPrefix, MsgSuffix, MsgNameColorCode + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Get the visuals: + AString MsgPrefix, MsgSuffix, MsgNameColorCode; + cRoot::Get()->GetRankManager().GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + + // Push the results: + S.Push(MsgPrefix); + S.Push(MsgSuffix); + S.Push(MsgNameColorCode); + return 3; +} + + + + + /** Binds cRankManager::GetRankPermissions */ static int tolua_cRankManager_GetRankPermissions(lua_State * L) { @@ -848,6 +883,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); + tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); tolua_function(tolua_S, "GroupExists", tolua_cRankManager_GroupExists); tolua_function(tolua_S, "IsGroupInRank", tolua_cRankManager_IsGroupInRank); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 8a3b19c15..3627afadb 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -1123,14 +1123,13 @@ void cRankManager::SetRankVisuals( const AString & a_MsgNameColorCode ) { - AStringVector res; try { SQLite::Statement stmt(m_DB, "UPDATE Rank SET MsgPrefix = ?, MsgSuffix = ?, MsgNameColorCode = ? WHERE Name = ?"); stmt.bind(1, a_MsgPrefix); stmt.bind(2, a_MsgSuffix); - stmt.bind(1, a_MsgNameColorCode); - stmt.bind(2, a_RankName); + stmt.bind(3, a_MsgNameColorCode); + stmt.bind(4, a_RankName); if (!stmt.executeStep()) { LOGINFO("%s: Rank %s not found, visuals not set.", __FUNCTION__, a_RankName.c_str()); @@ -1146,6 +1145,38 @@ void cRankManager::SetRankVisuals( +bool cRankManager::GetRankVisuals( + const AString & a_RankName, + AString & a_MsgPrefix, + AString & a_MsgSuffix, + AString & a_MsgNameColorCode +) +{ + try + { + SQLite::Statement stmt(m_DB, "SELECT MsgPrefix, MsgSuffix, MsgNameColorCode FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (!stmt.executeStep()) + { + // Rank not found + return false; + } + a_MsgPrefix = stmt.getColumn(0).getText(); + a_MsgSuffix = stmt.getColumn(1).getText(); + a_MsgNameColorCode = stmt.getColumn(2).getText(); + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get ranks from DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + + bool cRankManager::RankExists(const AString & a_RankName) { try diff --git a/src/RankManager.h b/src/RankManager.h index e13febdac..0a43bfe5d 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -121,6 +121,15 @@ public: const AString & a_MsgNameColorCode ); + /** Returns the message visuals of an existing rank. + Returns true if successful, false on error (rank doesn't exist). */ + bool GetRankVisuals( + const AString & a_RankName, + AString & a_MsgPrefix, + AString & a_MsgSuffix, + AString & a_MsgNameColorCode + ); + /** Returns true iff the specified rank exists in the DB. */ bool RankExists(const AString & a_RankName); -- cgit v1.2.3 From 2ab8e763927070eef76963d42933a0d9b87191c2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 9 Aug 2014 22:34:59 +0200 Subject: WebAdmin: Added GetURLEncodedString(). --- src/WebAdmin.cpp | 32 ++++++++++++++++++++++++++++++++ src/WebAdmin.h | 5 ++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index f5dc6fde7..ab6925e55 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -444,6 +444,38 @@ AString cWebAdmin::GetHTMLEscapedString(const AString & a_Input) +AString cWebAdmin::GetURLEncodedString(const AString & a_Input) +{ + // Translation table from nibble to hex: + static const char Hex[] = "0123456789abcdef"; + + // Preallocate the output to match input: + AString dst; + size_t len = a_Input.length(); + dst.reserve(len); + + // Loop over input and substitute whatever is needed: + for (size_t i = 0; i < len; i++) + { + char ch = a_Input[i]; + if (isalnum(ch) || (ch == '-') || (ch == '_') || (ch == '.') || (ch == '~')) + { + dst.push_back(ch); + } + else + { + dst.push_back('%'); + dst.push_back(Hex[(ch >> 4) & 0x0f]); + dst.push_back(Hex[ch & 0x0f]); + } + } // for i - a_Input[] + return dst; +} + + + + + AString cWebAdmin::GetBaseURL(const AStringVector & a_URLSplit) { AString BaseURL = "./"; diff --git a/src/WebAdmin.h b/src/WebAdmin.h index d679a097c..018a27b69 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -134,6 +134,9 @@ public: /** Escapes text passed into it, so it can be embedded into html. */ static AString GetHTMLEscapedString(const AString & a_Input); + + /** Escapes the string for use in an URL */ + static AString GetURLEncodedString(const AString & a_Input); AString GetIPv4Ports(void) const { return m_PortsIPv4; } AString GetIPv6Ports(void) const { return m_PortsIPv6; } @@ -141,7 +144,7 @@ public: // tolua_end /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ - AString GetBaseURL(const AStringVector& a_URLSplit); + static AString GetBaseURL(const AStringVector & a_URLSplit); protected: /** Common base class for request body data handlers */ -- cgit v1.2.3 From 50359ce65670badb72879f09fc9b2f77b2cbeae6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 9 Aug 2014 22:54:43 +0200 Subject: WebAdmin: Manually exported string conversion functions. ToLua generated an extra return value for GetHTMLEscapedString() and GetURLEncodedString(), making them difficult to use. --- src/Bindings/ManualBindings.cpp | 60 ++++++++++++++++++++++++++++++++++++++++- src/WebAdmin.h | 10 +++---- 2 files changed, 64 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f50bdd7de..c8eb5d138 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2128,6 +2128,62 @@ static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) +/** Binding for cWebAdmin::GetHTMLEscapedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) +{ + // Check the param types: + cLuaState S(tolua_S); + if ( + !S.CheckParamUserTable(1, "cWebAdmin") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetHTMLEscapedString(Input)); + return 1; +} + + + + + +/** Binding for cWebAdmin::GetURLEncodedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) +{ + // Check the param types: + cLuaState S(tolua_S); + if ( + !S.CheckParamUserTable(1, "cWebAdmin") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetURLEncodedString(Input)); + return 1; +} + + + + + static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) { cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, NULL); @@ -3264,7 +3320,9 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebAdmin"); - tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); + tolua_function(tolua_S, "GetHTMLEscapedString", tolua_AllToLua_cWebAdmin_GetHTMLEscapedString); + tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); + tolua_function(tolua_S, "GetURLEncodedString", tolua_AllToLua_cWebAdmin_GetURLEncodedString); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebPlugin"); diff --git a/src/WebAdmin.h b/src/WebAdmin.h index 018a27b69..f48e8ce9e 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -132,17 +132,17 @@ public: /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ AString GetBaseURL(const AString & a_URL); + AString GetIPv4Ports(void) const { return m_PortsIPv4; } + AString GetIPv6Ports(void) const { return m_PortsIPv6; } + + // tolua_end + /** Escapes text passed into it, so it can be embedded into html. */ static AString GetHTMLEscapedString(const AString & a_Input); /** Escapes the string for use in an URL */ static AString GetURLEncodedString(const AString & a_Input); - AString GetIPv4Ports(void) const { return m_PortsIPv4; } - AString GetIPv6Ports(void) const { return m_PortsIPv6; } - - // tolua_end - /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ static AString GetBaseURL(const AStringVector & a_URLSplit); -- cgit v1.2.3 From dcef688ccc0ae60b001ce40fd591a2dfafbac294 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 9 Aug 2014 22:34:59 +0200 Subject: WebAdmin: Added GetURLEncodedString(). --- src/WebAdmin.cpp | 32 ++++++++++++++++++++++++++++++++ src/WebAdmin.h | 5 ++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index f5dc6fde7..ab6925e55 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -444,6 +444,38 @@ AString cWebAdmin::GetHTMLEscapedString(const AString & a_Input) +AString cWebAdmin::GetURLEncodedString(const AString & a_Input) +{ + // Translation table from nibble to hex: + static const char Hex[] = "0123456789abcdef"; + + // Preallocate the output to match input: + AString dst; + size_t len = a_Input.length(); + dst.reserve(len); + + // Loop over input and substitute whatever is needed: + for (size_t i = 0; i < len; i++) + { + char ch = a_Input[i]; + if (isalnum(ch) || (ch == '-') || (ch == '_') || (ch == '.') || (ch == '~')) + { + dst.push_back(ch); + } + else + { + dst.push_back('%'); + dst.push_back(Hex[(ch >> 4) & 0x0f]); + dst.push_back(Hex[ch & 0x0f]); + } + } // for i - a_Input[] + return dst; +} + + + + + AString cWebAdmin::GetBaseURL(const AStringVector & a_URLSplit) { AString BaseURL = "./"; diff --git a/src/WebAdmin.h b/src/WebAdmin.h index d679a097c..018a27b69 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -134,6 +134,9 @@ public: /** Escapes text passed into it, so it can be embedded into html. */ static AString GetHTMLEscapedString(const AString & a_Input); + + /** Escapes the string for use in an URL */ + static AString GetURLEncodedString(const AString & a_Input); AString GetIPv4Ports(void) const { return m_PortsIPv4; } AString GetIPv6Ports(void) const { return m_PortsIPv6; } @@ -141,7 +144,7 @@ public: // tolua_end /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ - AString GetBaseURL(const AStringVector& a_URLSplit); + static AString GetBaseURL(const AStringVector & a_URLSplit); protected: /** Common base class for request body data handlers */ -- cgit v1.2.3 From b0dedb01977fe4cd7ebd51db5784d8ca415f1567 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 9 Aug 2014 22:54:43 +0200 Subject: WebAdmin: Manually exported string conversion functions. ToLua generated an extra return value for GetHTMLEscapedString() and GetURLEncodedString(), making them difficult to use. --- src/Bindings/ManualBindings.cpp | 60 ++++++++++++++++++++++++++++++++++++++++- src/WebAdmin.h | 10 +++---- 2 files changed, 64 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 8e6156d97..6b40cece8 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2128,6 +2128,62 @@ static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S) +/** Binding for cWebAdmin::GetHTMLEscapedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) +{ + // Check the param types: + cLuaState S(tolua_S); + if ( + !S.CheckParamUserTable(1, "cWebAdmin") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetHTMLEscapedString(Input)); + return 1; +} + + + + + +/** Binding for cWebAdmin::GetURLEncodedString. +Manual code required because ToLua generates an extra return value */ +static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) +{ + // Check the param types: + cLuaState S(tolua_S); + if ( + !S.CheckParamUserTable(1, "cWebAdmin") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the parameters: + AString Input; + S.GetStackValue(2, Input); + + // Convert and return: + S.Push(cWebAdmin::GetURLEncodedString(Input)); + return 1; +} + + + + + static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) { cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, NULL); @@ -3264,7 +3320,9 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebAdmin"); - tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); + tolua_function(tolua_S, "GetHTMLEscapedString", tolua_AllToLua_cWebAdmin_GetHTMLEscapedString); + tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins); + tolua_function(tolua_S, "GetURLEncodedString", tolua_AllToLua_cWebAdmin_GetURLEncodedString); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebPlugin"); diff --git a/src/WebAdmin.h b/src/WebAdmin.h index 018a27b69..f48e8ce9e 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -132,17 +132,17 @@ public: /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ AString GetBaseURL(const AString & a_URL); + AString GetIPv4Ports(void) const { return m_PortsIPv4; } + AString GetIPv6Ports(void) const { return m_PortsIPv6; } + + // tolua_end + /** Escapes text passed into it, so it can be embedded into html. */ static AString GetHTMLEscapedString(const AString & a_Input); /** Escapes the string for use in an URL */ static AString GetURLEncodedString(const AString & a_Input); - AString GetIPv4Ports(void) const { return m_PortsIPv4; } - AString GetIPv6Ports(void) const { return m_PortsIPv6; } - - // tolua_end - /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ static AString GetBaseURL(const AStringVector & a_URLSplit); -- cgit v1.2.3 From 5eb5411f1e9f3683e8ecb6448877ba6cf34b2dbf Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 10 Aug 2014 11:06:04 +0200 Subject: Removed an old and outdated comment. --- src/Generating/FinishGen.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index e8324095e..eb57a5faa 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -484,8 +484,6 @@ int cFinishGenSingleTopBlock::GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap void cFinishGenSingleTopBlock::GenFinish(cChunkDesc & a_ChunkDesc) { - // Add Lilypads on top of water surface in Swampland - int NumToGen = GetNumToGen(a_ChunkDesc.GetBiomeMap()); int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); -- cgit v1.2.3 From ecfae286064b4a8fcf6e4df38c09e8055e83de33 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 10 Aug 2014 11:40:33 +0200 Subject: Changed cStructGenOreNests to take a list of ores + the block to replace. --- src/Generating/ComposableGenerator.cpp | 52 +++++++++++++++++++++++++++++- src/Generating/StructGen.cpp | 58 ++++++---------------------------- src/Generating/StructGen.h | 26 ++++++++++++--- 3 files changed, 83 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index cedb9aeb7..79a92171f 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -400,7 +400,57 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "OreNests") == 0) { - m_FinishGens.push_back(new cStructGenOreNests(Seed)); + cStructGenOreNests::OreList Ores; + + // Coal vein + cStructGenOreNests::OreInfo CoalVein; + CoalVein.BlockType = E_BLOCK_COAL_ORE; + CoalVein.MaxHeight = 127; + CoalVein.NumNests = 50; + CoalVein.NestSize = 10; + Ores.push_back(CoalVein); + + // Iron vein + cStructGenOreNests::OreInfo IronVein; + IronVein.BlockType = E_BLOCK_IRON_ORE; + IronVein.MaxHeight = 64; + IronVein.NumNests = 14; + IronVein.NestSize = 6; + Ores.push_back(IronVein); + + // Gold vein + cStructGenOreNests::OreInfo GoldVein; + GoldVein.BlockType = E_BLOCK_GOLD_ORE; + GoldVein.MaxHeight = 32; + GoldVein.NumNests = 2; + GoldVein.NestSize = 6; + Ores.push_back(GoldVein); + + // Redstone vein + cStructGenOreNests::OreInfo RedstoneVein; + RedstoneVein.BlockType = E_BLOCK_REDSTONE_ORE; + RedstoneVein.MaxHeight = 16; + RedstoneVein.NumNests = 4; + RedstoneVein.NestSize = 6; + Ores.push_back(RedstoneVein); + + // Lapis vein + cStructGenOreNests::OreInfo LapisVein; + LapisVein.BlockType = E_BLOCK_LAPIS_ORE; + LapisVein.MaxHeight = 30; + LapisVein.NumNests = 2; + LapisVein.NestSize = 5; + Ores.push_back(LapisVein); + + // Diamond vein + cStructGenOreNests::OreInfo DiamondVein; + DiamondVein.BlockType = E_BLOCK_DIAMOND_ORE; + DiamondVein.MaxHeight = 15; + DiamondVein.NumNests = 1; + DiamondVein.NestSize = 4; + Ores.push_back(DiamondVein); + + m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); } else if (NoCaseCompare(*itr, "POCPieces") == 0) { diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index f7e609353..1a43f2b2e 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -12,45 +12,6 @@ -//////////////////////////////////////////////////////////////////////////////// -// cStructGenOreNests configuration: - -const int MAX_HEIGHT_COAL = 127; -const int NUM_NESTS_COAL = 50; -const int NEST_SIZE_COAL = 10; - -const int MAX_HEIGHT_IRON = 64; -const int NUM_NESTS_IRON = 14; -const int NEST_SIZE_IRON = 6; - -const int MAX_HEIGHT_REDSTONE = 16; -const int NUM_NESTS_REDSTONE = 4; -const int NEST_SIZE_REDSTONE = 6; - -const int MAX_HEIGHT_GOLD = 32; -const int NUM_NESTS_GOLD = 2; -const int NEST_SIZE_GOLD = 6; - -const int MAX_HEIGHT_DIAMOND = 15; -const int NUM_NESTS_DIAMOND = 1; -const int NEST_SIZE_DIAMOND = 4; - -const int MAX_HEIGHT_LAPIS = 30; -const int NUM_NESTS_LAPIS = 2; -const int NEST_SIZE_LAPIS = 5; - -const int MAX_HEIGHT_DIRT = 127; -const int NUM_NESTS_DIRT = 20; -const int NEST_SIZE_DIRT = 32; - -const int MAX_HEIGHT_GRAVEL = 70; -const int NUM_NESTS_GRAVEL = 15; -const int NEST_SIZE_GRAVEL = 32; - - - - - //////////////////////////////////////////////////////////////////////////////// // cStructGenTrees: @@ -311,14 +272,15 @@ void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); cChunkDef::BlockTypes & BlockTypes = a_ChunkDesc.GetBlockTypes(); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, BlockTypes, 1); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, BlockTypes, 2); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, BlockTypes, 3); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, BlockTypes, 4); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, BlockTypes, 5); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, BlockTypes, 6); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_DIRT, MAX_HEIGHT_DIRT, NUM_NESTS_DIRT, NEST_SIZE_DIRT, BlockTypes, 10); - GenerateOre(ChunkX, ChunkZ, E_BLOCK_GRAVEL, MAX_HEIGHT_GRAVEL, NUM_NESTS_GRAVEL, NEST_SIZE_GRAVEL, BlockTypes, 11); + + int seq = 1; + + // Generate the ores from the ore list. + for (OreList::iterator itr = m_OreList.begin(); itr != m_OreList.end(); ++itr) + { + GenerateOre(ChunkX, ChunkZ, itr->BlockType, itr->MaxHeight, itr->NumNests, itr->NestSize, BlockTypes, seq); + seq++; + } } @@ -376,7 +338,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore } int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ); - if (a_BlockTypes[Index] == E_BLOCK_STONE) + if (a_BlockTypes[Index] == m_ToReplace) { a_BlockTypes[Index] = a_OreType; } diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 9176bc192..e2fe8bc1a 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -76,11 +76,29 @@ class cStructGenOreNests : public cFinishGen { public: - cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} - + struct OreInfo + { + BLOCKTYPE BlockType; // The type of the nest. + int MaxHeight; // The highest possible a nest can occur + int NumNests; // How many nests per chunk + int NestSize; // The amount of blocks a nest can have. + }; + + typedef std::vector OreList; + + cStructGenOreNests(int a_Seed, OreList a_OreList, BLOCKTYPE a_ToReplace) : + m_Noise(a_Seed), + m_Seed(a_Seed), + m_OreList(a_OreList), + m_ToReplace(a_ToReplace) + {} + protected: - cNoise m_Noise; - int m_Seed; + cNoise m_Noise; + int m_Seed; + + OreList m_OreList; // A list of possible ores. + BLOCKTYPE m_ToReplace; // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; -- cgit v1.2.3 From 0ac3c67a21ae6fbd060322d65fcdad4f98148567 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 10 Aug 2014 11:48:05 +0200 Subject: Added NetherOreNests. It generates Nether Quarts. --- src/Generating/ComposableGenerator.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 79a92171f..1ae86a29f 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -398,6 +398,21 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth)); } + else if (NoCaseCompare(*itr, "NetherOreNests") == 0) + { + cStructGenOreNests::OreList Ores; + + // Quarts vein + cStructGenOreNests::OreInfo QuartsVein; + QuartsVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE; + QuartsVein.MaxHeight = 255; + QuartsVein.NumNests = 80; + QuartsVein.NestSize = 8; + Ores.push_back(QuartsVein); + + m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)); + + } else if (NoCaseCompare(*itr, "OreNests") == 0) { cStructGenOreNests::OreList Ores; -- cgit v1.2.3 From e529401dbb6d9c6de3b5e81b3308a478fe1a36db Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 10 Aug 2014 11:57:05 +0200 Subject: Added NaturalPatches generator It generates gravel and dirt. --- src/Generating/ComposableGenerator.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 1ae86a29f..58ad8fc2e 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -387,6 +387,28 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)); } + else if (NoCaseCompare(*itr, "NaturalPatches") == 0) + { + cStructGenOreNests::OreList Ores; + + // Dirt vein + cStructGenOreNests::OreInfo DirtVein; + DirtVein.BlockType = E_BLOCK_DIRT; + DirtVein.MaxHeight = 127; + DirtVein.NumNests = 20; + DirtVein.NestSize = 32; + Ores.push_back(DirtVein); + + // Gravel vein + cStructGenOreNests::OreInfo GravelVein; + GravelVein.BlockType = E_BLOCK_DIRT; + GravelVein.MaxHeight = 127; + GravelVein.NumNests = 20; + GravelVein.NestSize = 32; + Ores.push_back(GravelVein); + + m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); + } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); -- cgit v1.2.3 From cccc321384be18d4ac75e83abf3ce4d19a2a3d56 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 10 Aug 2014 16:46:03 +0200 Subject: Renamed functions. --- src/World.cpp | 6 +++--- src/World.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index ab46e886c..dc1d9fedf 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -243,7 +243,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin #endif m_Dimension(a_Dimension), m_IsSpawnExplicitlySet(false), - m_CycleDaylight(true), + m_IsDaylightCycleEnabled(true), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -832,7 +832,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_WorldAgeSecs += (double)a_Dt / 1000.0; m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - if (m_CycleDaylight) + if (m_IsDaylightCycleEnabled) { // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it m_TimeOfDaySecs += (double)a_Dt / 1000.0; @@ -2249,7 +2249,7 @@ void cWorld::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { int TimeOfDay = m_TimeOfDay; - if (!m_CycleDaylight) + if (!m_IsDaylightCycleEnabled) { TimeOfDay *= -1; if (TimeOfDay == 0) diff --git a/src/World.h b/src/World.h index 4e85087fc..6df1758e9 100644 --- a/src/World.h +++ b/src/World.h @@ -147,12 +147,12 @@ public: int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } /** Is the daylight cyclus enabled? */ - virtual bool IsDaylightCycleEnabled(void) const { return m_CycleDaylight; } + virtual bool IsDaylightCycleEnabled(void) const { return m_IsDaylightCycleEnabled; } /** Sets the daylight cyclus to true/false. */ - virtual void SetDoDaylightCycle(bool a_CycleDaylight) + virtual void SetDaylightCycleEnabled(bool a_IsDaylightCycleEnabled) { - m_CycleDaylight = a_CycleDaylight; + m_IsDaylightCycleEnabled = a_IsDaylightCycleEnabled; BroadcastTimeUpdate(); } @@ -879,7 +879,7 @@ private: bool m_BroadcastDeathMessages; bool m_BroadcastAchievementMessages; - bool m_CycleDaylight; // Is the daylight cyclus enabled? + bool m_IsDaylightCycleEnabled; double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs -- cgit v1.2.3 From f90078c09ff576d3f8af1554872c53afbdcd6fe0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 10 Aug 2014 16:48:20 +0200 Subject: Added IsDaylightCycleEnabled saving. --- src/World.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index dc1d9fedf..0ae7f80a6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -577,6 +577,7 @@ void cWorld::Start(void) m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); + m_IsDaylightCycleEnabled = IniFile.GetValueSetB("General", "IsDaylightCycleEnabled", true); int GameMode = IniFile.GetValueSetI("General", "Gamemode", (int)m_GameMode); int Weather = IniFile.GetValueSetI("General", "Weather", (int)m_Weather); @@ -798,6 +799,7 @@ void cWorld::Stop(void) IniFile.SetValueI("Physics", "TNTShrapnelLevel", (int)m_TNTShrapnelLevel); IniFile.SetValueB("Mechanics", "CommandBlocksEnabled", m_bCommandBlocksEnabled); IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes); + IniFile.SetValueB("General", "IsDaylightCycleEnabled", m_IsDaylightCycleEnabled); IniFile.SetValueI("General", "Weather", (int)m_Weather); IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay); IniFile.WriteFile(m_IniFileName); -- cgit v1.2.3 From ae611563919d123a93d6aab0eaf20c7423acce23 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 10 Aug 2014 17:08:22 +0200 Subject: Fixed swing arm animation when you ate. --- src/Entities/Player.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index d1d7349a6..8fa060a5d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -601,7 +601,6 @@ void cPlayer::FinishEating(void) // Send the packets: m_ClientHandle->SendEntityStatus(*this, esPlayerEatingAccepted); - m_World->BroadcastEntityAnimation(*this, 0); m_World->BroadcastEntityMetadata(*this); // consume the item: @@ -619,8 +618,8 @@ void cPlayer::FinishEating(void) // if the food is mushroom soup, return a bowl to the inventory if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP) { - cItem emptyBowl(E_ITEM_BOWL, 1, 0, ""); - GetInventory().AddItem(emptyBowl, true, true); + cItem EmptyBowl(E_ITEM_BOWL); + GetInventory().AddItem(EmptyBowl, true, true); } } @@ -631,7 +630,6 @@ void cPlayer::FinishEating(void) void cPlayer::AbortEating(void) { m_EatingFinishTick = -1; - m_World->BroadcastEntityAnimation(*this, 0); m_World->BroadcastEntityMetadata(*this); } -- cgit v1.2.3 From 938bf1df69ae88ecdd85029d20bfd09d4fbf7618 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 10 Aug 2014 17:12:08 +0200 Subject: Changed comment. --- src/Blocks/BlockSlab.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 49f00c88c..e67f0e8b3 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -119,9 +119,7 @@ public: return; } - /* Sends the slab back to the client. - The normal back sending adds the block face to the locations, but this don't work because the Y-Coordinate with the block face - is one higher than the real slab position. */ + // Sends the slab back to the client. It's to refuse a doubleslab placement. a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } -- cgit v1.2.3 From 42bad0edec58f42e4072360c52870d3be9ced3c5 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 10 Aug 2014 20:06:03 +0200 Subject: Added a comment and simplified code. --- src/ClientHandle.cpp | 9 +++------ src/World.cpp | 7 ++----- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 286c17513..37d7edbc1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -341,15 +341,12 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, m_Protocol->SendWeather(World->GetWeather()); } - // Send time + // Send time: Int64 TimeOfDay = World->GetTimeOfDay(); if (!World->IsDaylightCycleEnabled()) { - TimeOfDay *= -1; - if (TimeOfDay == 0) - { - TimeOfDay = -1; - } + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + TimeOfDay = std::min(-TimeOfDay, -1); } m_Protocol->SendTimeUpdate(World->GetWorldAge(), TimeOfDay); diff --git a/src/World.cpp b/src/World.cpp index 0ae7f80a6..dcca0519e 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2253,11 +2253,8 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) int TimeOfDay = m_TimeOfDay; if (!m_IsDaylightCycleEnabled) { - TimeOfDay *= -1; - if (TimeOfDay == 0) - { - TimeOfDay = -1; - } + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + TimeOfDay = std::min(-TimeOfDay, -1); } cCSLock Lock(m_CSPlayers); -- cgit v1.2.3 From 806d0936dc94f235858ffe1772a6215f86c5d000 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 19:34:11 +0100 Subject: First Implementatation of new Loggin framework --- src/Bindings/LuaFunctions.h | 2 +- src/Bindings/ManualBindings.cpp | 10 +- src/CMakeLists.txt | 6 +- src/CompositeChat.cpp | 24 ++-- src/CompositeChat.h | 2 +- src/Globals.h | 2 +- src/MCLogger.cpp | 267 ---------------------------------------- src/MCLogger.h | 95 -------------- src/OSSupport/File.cpp | 5 +- src/OSSupport/File.h | 3 +- src/Root.cpp | 26 ++-- src/Root.h | 2 - src/StringUtils.h | 1 - src/main.cpp | 2 + 14 files changed, 49 insertions(+), 398 deletions(-) delete mode 100644 src/MCLogger.cpp delete mode 100644 src/MCLogger.h (limited to 'src') diff --git a/src/Bindings/LuaFunctions.h b/src/Bindings/LuaFunctions.h index 2ea37d7a4..6a645ed53 100644 --- a/src/Bindings/LuaFunctions.h +++ b/src/Bindings/LuaFunctions.h @@ -1,6 +1,6 @@ #pragma once -#include "../MCLogger.h" +#include "LogDispacher.h" #include // tolua_begin diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9ba1501c5..d792cd0ee 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -168,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { // If the param is a cCompositeChat, read the log level from it: - cMCLogger::eLogLevel LogLevel = cMCLogger::llRegular; + Logger::eLogLevel LogLevel = Logger::llRegular; tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { @@ -176,7 +176,7 @@ static int tolua_LOG(lua_State * tolua_S) } // Log the message: - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); + Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -186,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llInfo); + Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llInfo); return 0; } @@ -196,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llWarning); + Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llWarning); return 0; } @@ -206,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llError); + Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llError); return 0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db9c61082..0feee4fcb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required (VERSION 2.8.2) project (MCServer) + include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include") @@ -41,8 +42,9 @@ SET (SRCS LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp + Listeners.cpp Log.cpp - MCLogger.cpp + LogDispacher.cpp Map.cpp MapManager.cpp MobCensus.cpp @@ -108,7 +110,7 @@ SET (HDRS LinearInterpolation.h LinearUpscale.h Log.h - MCLogger.h + LogDispacher.h Map.h MapManager.h Matrix4.h diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index f1a797897..b702447be 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -353,23 +353,23 @@ AString cCompositeChat::ExtractText(void) const -cMCLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +Logger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) { switch (a_MessageType) { - case mtCustom: return cMCLogger::llRegular; - case mtFailure: return cMCLogger::llWarning; - case mtInformation: return cMCLogger::llInfo; - case mtSuccess: return cMCLogger::llRegular; - case mtWarning: return cMCLogger::llWarning; - case mtFatal: return cMCLogger::llError; - case mtDeath: return cMCLogger::llRegular; - case mtPrivateMessage: return cMCLogger::llRegular; - case mtJoin: return cMCLogger::llRegular; - case mtLeave: return cMCLogger::llRegular; + case mtCustom: return Logger::llRegular; + case mtFailure: return Logger::llWarning; + case mtInformation: return Logger::llInfo; + case mtSuccess: return Logger::llRegular; + case mtWarning: return Logger::llWarning; + case mtFatal: return Logger::llError; + case mtDeath: return Logger::llRegular; + case mtPrivateMessage: return Logger::llRegular; + case mtJoin: return Logger::llRegular; + case mtLeave: return Logger::llRegular; } ASSERT(!"Unhandled MessageType"); - return cMCLogger::llError; + return Logger::llError; } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 1ad196f1d..cc7c446c3 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -196,7 +196,7 @@ public: /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ - static cMCLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + static Logger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); protected: /** All the parts that */ diff --git a/src/Globals.h b/src/Globals.h index 60ee456c9..ae7a68e7f 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -249,7 +249,7 @@ template class SizeChecker; #include "OSSupport/Event.h" #include "OSSupport/Thread.h" #include "OSSupport/File.h" - #include "MCLogger.h" + #include "LogDispacher.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp deleted file mode 100644 index 044e83937..000000000 --- a/src/MCLogger.cpp +++ /dev/null @@ -1,267 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include -#include "Log.h" - - - - - -cMCLogger * cMCLogger::s_MCLogger = NULL; - -#ifdef _WIN32 - #include // Needed for _isatty(), not available on Linux - - HANDLE g_Console = GetStdHandle(STD_OUTPUT_HANDLE); - WORD g_DefaultConsoleAttrib = 0x07; -#elif defined (__linux) && !defined(ANDROID_NDK) - #include // Needed for isatty() on Linux -#endif - - - - - -cMCLogger * cMCLogger::GetInstance(void) -{ - return s_MCLogger; -} - - - - - -cMCLogger::cMCLogger(void): - m_ShouldColorOutput(false) -{ - AString FileName; - Printf(FileName, "LOG_%d.txt", (int)time(NULL)); - InitLog(FileName); -} - - - - - -cMCLogger::cMCLogger(const AString & a_FileName) -{ - InitLog(a_FileName); -} - - - - - -cMCLogger::~cMCLogger() -{ - m_Log->Log("--- Stopped Log ---\n"); - delete m_Log; - m_Log = NULL; - if (this == s_MCLogger) - { - s_MCLogger = NULL; - } -} - - - - - -void cMCLogger::InitLog(const AString & a_FileName) -{ - m_Log = new cLog(a_FileName); - m_Log->Log("--- Started Log ---\n"); - - s_MCLogger = this; - - #ifdef _WIN32 - // See whether we are writing to a console the default console attrib: - m_ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); - if (m_ShouldColorOutput) - { - CONSOLE_SCREEN_BUFFER_INFO sbi; - GetConsoleScreenBufferInfo(g_Console, &sbi); - g_DefaultConsoleAttrib = sbi.wAttributes; - } - #elif defined (__linux) && !defined(ANDROID_NDK) - m_ShouldColorOutput = isatty(fileno(stdout)); - // TODO: Check if the terminal supports colors, somehow? - #endif -} - - - - - -void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) -{ - switch (a_LogLevel) - { - case llRegular: - { - LOG("%s", a_Text); - break; - } - case llInfo: - { - LOGINFO("%s", a_Text); - break; - } - case llWarning: - { - LOGWARN("%s", a_Text); - break; - } - case llError: - { - LOGERROR("%s", a_Text); - break; - } - } -} - - - - - -void cMCLogger::Log(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Info(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csInfo); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Warn(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csWarning); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Error(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csError); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::SetColor(eColorScheme a_Scheme) -{ - if (!m_ShouldColorOutput) - { - return; - } - #ifdef _WIN32 - WORD Attrib = 0x07; // by default, gray on black - switch (a_Scheme) - { - case csRegular: Attrib = 0x07; break; // Gray on black - case csInfo: Attrib = 0x0e; break; // Yellow on black - case csWarning: Attrib = 0x0c; break; // Read on black - case csError: Attrib = 0xc0; break; // Black on red - default: ASSERT(!"Unhandled color scheme"); - } - SetConsoleTextAttribute(g_Console, Attrib); - #elif defined(__linux) && !defined(ANDROID_NDK) - switch (a_Scheme) - { - case csRegular: printf("\x1b[0m"); break; // Whatever the console default is - case csInfo: printf("\x1b[33;1m"); break; // Yellow on black - case csWarning: printf("\x1b[31;1m"); break; // Red on black - case csError: printf("\x1b[1;33;41;1m"); break; // Yellow on red - default: ASSERT(!"Unhandled color scheme"); - } - #endif -} - - - - - -void cMCLogger::ResetColor(void) -{ - if (!m_ShouldColorOutput) - { - return; - } - #ifdef _WIN32 - SetConsoleTextAttribute(g_Console, g_DefaultConsoleAttrib); - #elif defined(__linux) && !defined(ANDROID_NDK) - printf("\x1b[0m"); - #endif -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Global functions - -void LOG(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Log( a_Format, argList); - va_end(argList); -} - -void LOGINFO(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Info( a_Format, argList); - va_end(argList); -} - -void LOGWARN(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Warn( a_Format, argList); - va_end(argList); -} - -void LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Error( a_Format, argList); - va_end(argList); -} - - - - diff --git a/src/MCLogger.h b/src/MCLogger.h deleted file mode 100644 index aa3a52d02..000000000 --- a/src/MCLogger.h +++ /dev/null @@ -1,95 +0,0 @@ - -#pragma once - - - - -class cLog; - - - - - -class cMCLogger -{ -public: - enum eLogLevel - { - llRegular, - llInfo, - llWarning, - llError, - }; - // tolua_end - - /** Creates a logger with the default filename, "logs/LOG_.log" */ - cMCLogger(void); - - /** Creates a logger with the specified filename inside "logs" folder */ - cMCLogger(const AString & a_FileName); - - ~cMCLogger(); - - void Log (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Info (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Warn (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Error(const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - - /** Logs the simple text message at the specified log level. */ - void LogSimple(const char * a_Text, eLogLevel a_LogLevel = llRegular); - - static cMCLogger * GetInstance(); -private: - enum eColorScheme - { - csRegular, - csInfo, - csWarning, - csError, - } ; - - cCriticalSection m_CriticalSection; - cLog * m_Log; - static cMCLogger * s_MCLogger; - bool m_ShouldColorOutput; - - - /// Sets the specified color scheme in the terminal (TODO: if coloring available) - void SetColor(eColorScheme a_Scheme); - - /// Resets the color back to whatever is the default in the terminal - void ResetColor(void); - - /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this - void InitLog(const AString & a_FileName); -}; - - - - - -extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); - - - - - -// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: -#ifdef _DEBUG - #define LOGD LOG -#else - #define LOGD(...) -#endif // _DEBUG - - - - - -#define LOGWARNING LOGWARN - - - - diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index ff6fb5898..af8a832f6 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -70,6 +70,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) case fmRead: Mode = "rb"; break; case fmWrite: Mode = "wb"; break; case fmReadWrite: Mode = "rb+"; break; + case fmAppend: Mode = "a+"; break; } if (Mode == NULL) { @@ -255,7 +256,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) return -1; } - int DataSize = GetSize() - Tell(); + size_t DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly a_Contents.assign((size_t)DataSize, '\0'); @@ -459,7 +460,7 @@ int cFile::Printf(const char * a_Fmt, ...) va_start(args, a_Fmt); AppendVPrintf(buf, a_Fmt, args); va_end(args); - return Write(buf.c_str(), (int)buf.length()); + return Write(buf.c_str(), buf.length()); } diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 2a7ecf0ed..8891511c4 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -62,7 +62,8 @@ public: { fmRead, // Read-only. If the file doesn't exist, object will not be valid fmWrite, // Write-only. If the file already exists, it will be overwritten - fmReadWrite // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file } ; /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ diff --git a/src/Root.cpp b/src/Root.cpp index c20cf0d21..72048b631 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -18,6 +18,7 @@ #include "CommandOutput.h" #include "DeadlockDetect.h" #include "OSSupport/Timer.h" +#include "Listeners.h" #include "inifile/iniFile.h" @@ -51,7 +52,6 @@ cRoot::cRoot(void) : m_FurnaceRecipe(NULL), m_WebAdmin(NULL), m_PluginManager(NULL), - m_Log(NULL), m_bStop(false), m_bRestart(false) { @@ -105,10 +105,15 @@ void cRoot::Start(void) HMENU hmenu = GetSystemMenu(hwnd, FALSE); EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif + + Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); + Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); + Logger::GetInstance().AttachListener(consoleLogListener); + Logger::GetInstance().AttachListener(fileLogListener); + + LOG("--- Started Log ---\n"); cDeadlockDetect dd; - delete m_Log; - m_Log = new cMCLogger(); m_bStop = false; while (!m_bStop) @@ -249,8 +254,13 @@ void cRoot::Start(void) delete m_Server; m_Server = NULL; LOG("Shutdown successful!"); } - - delete m_Log; m_Log = NULL; + + LOG("--- Stopped Log ---"); + + Logger::GetInstance().DetachListener(consoleLogListener); + delete consoleLogListener; + Logger::GetInstance().DetachListener(fileLogListener); + delete fileLogListener; } @@ -274,15 +284,15 @@ void cRoot::LoadWorlds(cIniFile & IniFile) m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; // Then load the other worlds - unsigned int KeyNum = IniFile.FindKey("Worlds"); - unsigned int NumWorlds = IniFile.GetNumValues(KeyNum); + int KeyNum = IniFile.FindKey("Worlds"); + int NumWorlds = IniFile.GetNumValues(KeyNum); if (NumWorlds <= 0) { return; } bool FoundAdditionalWorlds = false; - for (unsigned int i = 0; i < NumWorlds; i++) + for (int i = 0; i < NumWorlds; i++) { AString ValueName = IniFile.GetValueName(KeyNum, i); if (ValueName.compare("World") != 0) diff --git a/src/Root.h b/src/Root.h index 1cd175ab4..6840efcbe 100644 --- a/src/Root.h +++ b/src/Root.h @@ -196,8 +196,6 @@ private: cMojangAPI m_MojangAPI; cHTTPServer m_HTTPServer; - cMCLogger * m_Log; - bool m_bStop; bool m_bRestart; diff --git a/src/StringUtils.h b/src/StringUtils.h index 142aaf59b..3d4379352 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -12,7 +12,6 @@ - typedef std::string AString; typedef std::vector AStringVector; typedef std::list AStringList; diff --git a/src/main.cpp b/src/main.cpp index 106233342..e40035538 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,6 +273,8 @@ int main( int argc, char **argv) } } // for i - argv[] + Logger::InitiateMultithreading(); + #if !defined(ANDROID_NDK) try #endif -- cgit v1.2.3 From bf0050e066af60b5f4060b298118d74cf84dc299 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 19:44:49 +0100 Subject: Added forgoten files --- src/Listeners.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Listeners.h | 21 +++++ src/LogDispacher.cpp | 115 +++++++++++++++++++++++++ src/LogDispacher.h | 85 +++++++++++++++++++ 4 files changed, 457 insertions(+) create mode 100644 src/Listeners.cpp create mode 100644 src/Listeners.h create mode 100644 src/LogDispacher.cpp create mode 100644 src/LogDispacher.h (limited to 'src') diff --git a/src/Listeners.cpp b/src/Listeners.cpp new file mode 100644 index 000000000..384dcaf91 --- /dev/null +++ b/src/Listeners.cpp @@ -0,0 +1,236 @@ + +#include "Globals.h" + +#include "Listeners.h" + +#if defined(_WIN32) + #include // Needed for _isatty(), not available on Linux +#elif defined(__linux) && !defined(ANDROID_NDK) + #include // Needed for isatty() on Linux +#elif defined(ANDROID_NDK) + #include +#endif + + +namespace Logger +{ + + #if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) + class cColouredConsoleListener + : public cLoggerListener + { + + virtual void SetLogColour(eLogLevel a_LogLevel) = 0; + virtual void SetDefaultLogColour() = 0; + + virtual void Log(AString a_Message, eLogLevel a_LogLevel) override + { + SetLogColour(a_LogLevel); + puts(a_Message.c_str()); + SetDefaultLogColour(); + } + }; + #endif + + #ifdef _WIN32 + class cWindowsConsoleListener + : public cColouredConsoleListener + { + public: + cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : + m_Console(a_Console), + m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) + { + } + + #ifdef DEBUG + virtual void Log(AString a_Message, eLogLevel a_LogLevel) override + { + cColouredConsoleListener::Log(a_Message, a_LogLevel); + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA(a_Message.c_str()); + } + #endif // _WIN32 + + + virtual void SetLogColour(eLogLevel a_LogLevel) override + { + // by default, gray on black + WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + switch (a_LogLevel) + { + case llRegular: + // Gray on black + Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + case llInfo: + // Yellow on black + Attrib = FOREGROUND_GREEN | ; + break; + case llWarning: + // Red on black + Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + case llError: + // Black on red + Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; + break; + } + SetConsoleTextAttribute(m_Console, Attrib); + } + virtual void SetDefaultLogColour() override + { + SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); + } + private: + HANDLE m_Console; + WORD m_DefaultConsoleAttrib; + }; + #elif defined (__linux) && !defined(ANDROID_NDK) + class cLinuxConsoleListener + : public cColouredConsoleListener + { + public: + virtual void SetLogColour(eLogLevel a_LogLevel) override + { + switch (a_LogLevel) + { + case llRegular: + // Whatever the console default is + printf("\x1b[0m"); + break; + case llInfo: + // Yellow on black + printf("\x1b[33;1m"); + break; + case llWarning: + // Red on black + printf("\x1b[31;1m"); + break; + case llError: + // Yellow on red + printf("\x1b[1;33;41;1m"); + break; + } + } + virtual void SetDefaultLogColour() override + { + // Whatever the console default is + printf("\x1b[0m"); + } + }; + #elif defined(ANDROID_NDK) + class cAndroidConsoleListener + : public cLoggerListener + { + public: + virtual void Log(AString a_Message, eLogLevel a_LogLevel) override + { + android_LogPriority AndroidLogLevel; + switch (a_LogLevel) + { + case llRegular: + AndroidLogLevel = ANDROID_LOG_VERBOSE; + break; + case llInfo: + AndroidLogLevel = ANDROID_LOG_INFO; + break; + case llWarning: + AndroidLogLevel = ANDROID_LOG_WARNING; + break; + case llError: + AndroidLogLevel = ANDROID_LOG_ERROR; + break; + } + __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); + } + }; + #endif + + class cVanillaCPPConsoleListener + : public cLoggerListener + { + public: + virtual void Log(AString a_Message, eLogLevel a_LogLevel) override + { + AString LogLevelString; + switch (a_LogLevel) + { + case llRegular: + LogLevelString = "Log"; + break; + case llInfo: + LogLevelString = "Info"; + break; + case llWarning: + LogLevelString = "Warning"; + break; + case llError: + LogLevelString = "Error"; + break; + } + printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + } + }; + + + + cLoggerListener * MakeConsoleListener() + { + #ifdef _WIN32 + // See whether we are writing to a console the default console attrib: + bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); + if (ShouldColorOutput) + { + CONSOLE_SCREEN_BUFFER_INFO sbi; + HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(Console, &sbi); + WORD DefaultConsoleAttrib = sbi.wAttributes; + return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); + } else { + return new cVanillaCPPConsoleListener(); + } + + #elif defined (__linux) && !defined(ANDROID_NDK) + // TODO: lookup terminal in terminfo + if (isatty(fileno(stdout))) + { + return new cLinuxConsoleListener(); + } else { + return new cVanillaCPPConsoleListener(); + } + #else + return new cVanillaCPPConsoleListener(); + #endif + } + + cFileListener::cFileListener() + { + cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); + AString FileName; + FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); + m_File.Open(FileName, cFile::fmAppend); + } + + void cFileListener::Log(AString a_Message, eLogLevel a_LogLevel) + { + AString LogLevelString; + switch (a_LogLevel) + { + case llRegular: + LogLevelString = "Log"; + break; + case llInfo: + LogLevelString = "Info"; + break; + case llWarning: + LogLevelString = "Warning"; + break; + case llError: + LogLevelString = "Error"; + break; + } + m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + } + +} diff --git a/src/Listeners.h b/src/Listeners.h new file mode 100644 index 000000000..bc29d0c06 --- /dev/null +++ b/src/Listeners.h @@ -0,0 +1,21 @@ + +#include "LogDispacher.h" + +namespace Logger +{ + + class cFileListener + : public cLoggerListener + { + public: + + cFileListener(); + cFileListener(AString a_Filename); + + virtual void Log(AString a_Message, eLogLevel a_LogLevel) override; + private: + cFile m_File; + }; + + cLoggerListener * MakeConsoleListener(); +} diff --git a/src/LogDispacher.cpp b/src/LogDispacher.cpp new file mode 100644 index 000000000..337d718e6 --- /dev/null +++ b/src/LogDispacher.cpp @@ -0,0 +1,115 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Log.h" +#include "OSSupport/IsThread.h" + + + +namespace Logger +{ + + cLogDispacher & GetInstance(void) + { + static cLogDispacher Instance; + return Instance; + } + + void InitiateMultithreading() + { + GetInstance(); + } + + void cLogDispacher::LogSimple(AString a_Message, eLogLevel a_LogLevel) + { + time_t rawtime; + time ( &rawtime); + + struct tm* timeinfo; + #ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); + #else + timeinfo = localtime( &rawtime); + #endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #endif + + + cCSLock Lock(m_CriticalSection); + for(size_t i = 0; i < m_LogListeners.size(); i++) + { + m_LogListeners[i]->Log(a_Message, a_LogLevel); + } + } + + + + + + void cLogDispacher::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) + { + AString Message; + AppendVPrintf(Message, a_Format, a_ArgList); + LogSimple(Message, a_LogLevel); + } + + void cLogDispacher::AttachListener(Logger::cLoggerListener * a_Listener) + { + cCSLock Lock(m_CriticalSection); + m_LogListeners.push_back(a_Listener); + } + + void cLogDispacher::DetachListener(Logger::cLoggerListener * a_Listener) + { + cCSLock Lock(m_CriticalSection); + m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); + } +}; + + + +//////////////////////////////////////////////////////////////////////////////// +// Global functions + +void LOG(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Logger::GetInstance().Log(a_Format, Logger::llRegular, argList); + va_end(argList); +} + +void LOGINFO(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Logger::GetInstance().Log( a_Format, Logger::llInfo, argList); + va_end(argList); +} + +void LOGWARN(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Logger::GetInstance().Log( a_Format, Logger::llWarning, argList); + va_end(argList); +} + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + Logger::GetInstance().Log( a_Format, Logger::llError, argList); + va_end(argList); +} + + + + diff --git a/src/LogDispacher.h b/src/LogDispacher.h new file mode 100644 index 000000000..31b3b3fc1 --- /dev/null +++ b/src/LogDispacher.h @@ -0,0 +1,85 @@ + +#pragma once + + + +class cLog; + + +namespace Logger +{ + + enum eLogLevel + { + llRegular, + llInfo, + llWarning, + llError, + }; + + class cLogDispacher; + + // Must be called before calling GetInstance in a multithreaded context + void InitiateMultithreading(); + + cLogDispacher & GetInstance(void); + + class cLoggerListener + { + public: + virtual void Log(AString a_Message, eLogLevel a_LogLevel) = 0; + + virtual ~cLoggerListener(){} + }; + + class cLogDispacher + { + public: + + void Log (const char * a_Format, Logger::eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); + + /** Logs the simple text message at the specified log level. */ + void LogSimple(AString a_Message, Logger::eLogLevel a_LogLevel = Logger::llRegular); + + void AttachListener(Logger::cLoggerListener * a_Listener); + void DetachListener(Logger::cLoggerListener * a_Listener); + + private: + + cCriticalSection m_CriticalSection; + std::vector m_LogListeners; + + }; + +} + + + + + + +extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); + + + + + +// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: +#ifdef _DEBUG + #define LOGD LOG +#else + #define LOGD(...) +#endif // _DEBUG + + + + + +#define LOGWARNING LOGWARN + + + + -- cgit v1.2.3 From be780b380ee91f5de27eecb3d8809506d4198534 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 20:10:47 +0100 Subject: Fixed Tools to work with new logging framework --- src/CMakeLists.txt | 2 - src/Log.cpp | 169 --------------------------------------------------- src/Log.h | 30 --------- src/LogDispacher.cpp | 1 - src/LogDispacher.h | 4 -- 5 files changed, 206 deletions(-) delete mode 100644 src/Log.cpp delete mode 100644 src/Log.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0feee4fcb..bca6a2eb0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,7 +43,6 @@ SET (SRCS LineBlockTracer.cpp LinearInterpolation.cpp Listeners.cpp - Log.cpp LogDispacher.cpp Map.cpp MapManager.cpp @@ -109,7 +108,6 @@ SET (HDRS LineBlockTracer.h LinearInterpolation.h LinearUpscale.h - Log.h LogDispacher.h Map.h MapManager.h diff --git a/src/Log.cpp b/src/Log.cpp deleted file mode 100644 index 7686a0fb4..000000000 --- a/src/Log.cpp +++ /dev/null @@ -1,169 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Log.h" - -#include -#include -#include "OSSupport/IsThread.h" - -#if defined(ANDROID_NDK) - #include - #include "ToJava.h" -#endif - - - - -cLog* cLog::s_Log = NULL; - -cLog::cLog(const AString & a_FileName) - : m_File(NULL) -{ - s_Log = this; - - // create logs directory - cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); - - OpenLog((FILE_IO_PREFIX + AString("logs/") + a_FileName).c_str()); -} - - - - - -cLog::~cLog() -{ - CloseLog(); - s_Log = NULL; -} - - - - - -cLog * cLog::GetInstance() -{ - if (s_Log != NULL) - { - return s_Log; - } - - new cLog("log.txt"); - return s_Log; -} - - - - - -void cLog::CloseLog() -{ - if (m_File) - fclose (m_File); - m_File = 0; -} - - - - - -void cLog::OpenLog( const char* a_FileName) -{ - if (m_File) fclose (m_File); - #ifdef _MSC_VER - fopen_s( &m_File, a_FileName, "a+"); - #else - m_File = fopen(a_FileName, "a+"); - #endif -} - - - - - -void cLog::ClearLog() -{ - #ifdef _MSC_VER - if (fopen_s( &m_File, "log.txt", "w") == 0) - fclose (m_File); - #else - m_File = fopen("log.txt", "w"); - if (m_File) - fclose (m_File); - #endif - m_File = NULL; -} - - - - - -void cLog::Log(const char * a_Format, va_list argList) -{ - AString Message; - AppendVPrintf(Message, a_Format, argList); - - time_t rawtime; - time ( &rawtime); - - struct tm* timeinfo; -#ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); -#else - timeinfo = localtime( &rawtime); -#endif - - AString Line; - #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #endif - if (m_File) - { - fprintf(m_File, "%s\n", Line.c_str()); - fflush(m_File); - } - - // Print to console: -#if defined(ANDROID_NDK) - // __android_log_vprint(ANDROID_LOG_ERROR, "MCServer", a_Format, argList); - __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); - // CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line); -#else - printf("%s", Line.c_str()); -#endif - - #if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA((Line + "\n").c_str()); - #endif // _WIN32 -} - - - - - -void cLog::Log(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Log(a_Format, argList); - va_end(argList); -} - - - - - -void cLog::SimpleLog(const char * a_String) -{ - Log("%s", a_String); -} - - - - diff --git a/src/Log.h b/src/Log.h deleted file mode 100644 index dc88aa92f..000000000 --- a/src/Log.h +++ /dev/null @@ -1,30 +0,0 @@ - -#pragma once - - - - - -class cLog -{ -private: - FILE * m_File; - static cLog * s_Log; - -public: - cLog(const AString & a_FileName); - ~cLog(); - void Log(const char * a_Format, va_list argList) FORMATSTRING(2, 0); - void Log(const char * a_Format, ...) FORMATSTRING(2, 3); - // tolua_begin - void SimpleLog(const char * a_String); - void OpenLog(const char * a_FileName); - void CloseLog(); - void ClearLog(); - static cLog* GetInstance(); -}; - - - - - diff --git a/src/LogDispacher.cpp b/src/LogDispacher.cpp index 337d718e6..abca6a898 100644 --- a/src/LogDispacher.cpp +++ b/src/LogDispacher.cpp @@ -1,7 +1,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "Log.h" #include "OSSupport/IsThread.h" diff --git a/src/LogDispacher.h b/src/LogDispacher.h index 31b3b3fc1..1472b392a 100644 --- a/src/LogDispacher.h +++ b/src/LogDispacher.h @@ -2,10 +2,6 @@ #pragma once - -class cLog; - - namespace Logger { -- cgit v1.2.3 From 63a07b7ffc0d34beba6752c3c1f4f5771eb2c36b Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 20:47:16 +0100 Subject: Fixed potential crash in Player.cpp Fixes CID 71780 If ShouldBroadcastDeathMessages is false the pointer would fall through to a check agaist it being a player --- src/Entities/Player.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8fa060a5d..8667344c7 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -906,6 +906,10 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) } GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str())); } + else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough + { + // no-op + } else if (a_TDI.Attacker->IsPlayer()) { cPlayer * Killer = (cPlayer *)a_TDI.Attacker; -- cgit v1.2.3 From 07103ed9d7af1c37623d6c8c96ec5084938c244b Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 21:26:28 +0100 Subject: Spaces --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8667344c7..608316e9a 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -906,7 +906,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) } GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str())); } - else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough + else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough { // no-op } -- cgit v1.2.3 From d95768d01a93a14df38f6e0e33ca180b779c5df0 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 10 Aug 2014 22:36:02 +0200 Subject: Bunch of tweaks: Renamed Quarts to Quartz Using const_iterator instead of iterator Used CheckBasicStyle script to find style errors --- src/Generating/ComposableGenerator.cpp | 14 +++++++------- src/Generating/StructGen.cpp | 2 +- src/Generating/StructGen.h | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 58ad8fc2e..2f575fe27 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -424,13 +424,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { cStructGenOreNests::OreList Ores; - // Quarts vein - cStructGenOreNests::OreInfo QuartsVein; - QuartsVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE; - QuartsVein.MaxHeight = 255; - QuartsVein.NumNests = 80; - QuartsVein.NestSize = 8; - Ores.push_back(QuartsVein); + // Quartz vein + cStructGenOreNests::OreInfo QuartzVein; + QuartzVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE; + QuartzVein.MaxHeight = 255; + QuartzVein.NumNests = 80; + QuartzVein.NestSize = 8; + Ores.push_back(QuartzVein); m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)); diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 1a43f2b2e..731324b0d 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -276,7 +276,7 @@ void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) int seq = 1; // Generate the ores from the ore list. - for (OreList::iterator itr = m_OreList.begin(); itr != m_OreList.end(); ++itr) + for (OreList::const_iterator itr = m_OreList.begin(); itr != m_OreList.end(); ++itr) { GenerateOre(ChunkX, ChunkZ, itr->BlockType, itr->MaxHeight, itr->NumNests, itr->NestSize, BlockTypes, seq); seq++; diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index e2fe8bc1a..55d5bc1c7 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -78,16 +78,16 @@ class cStructGenOreNests : public: struct OreInfo { - BLOCKTYPE BlockType; // The type of the nest. - int MaxHeight; // The highest possible a nest can occur - int NumNests; // How many nests per chunk - int NestSize; // The amount of blocks a nest can have. + BLOCKTYPE BlockType; // The type of the nest. + int MaxHeight; // The highest possible a nest can occur + int NumNests; // How many nests per chunk + int NestSize; // The amount of blocks a nest can have. }; typedef std::vector OreList; - cStructGenOreNests(int a_Seed, OreList a_OreList, BLOCKTYPE a_ToReplace) : - m_Noise(a_Seed), + cStructGenOreNests(int a_Seed, OreList a_OreList, BLOCKTYPE a_ToReplace) : + m_Noise(a_Seed), m_Seed(a_Seed), m_OreList(a_OreList), m_ToReplace(a_ToReplace) @@ -97,7 +97,7 @@ protected: cNoise m_Noise; int m_Seed; - OreList m_OreList; // A list of possible ores. + OreList m_OreList; // A list of possible ores. BLOCKTYPE m_ToReplace; // cFinishGen override: -- cgit v1.2.3 From 5623a045f598a068a7bae77cc3acad62f6160452 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 22:06:56 +0100 Subject: Fixed potential null dereference Fixes CID 70466 --- src/BlockEntities/HopperEntity.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 48d3b8dcc..88e7b8e1b 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -549,13 +549,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ) { // Try the chest directly connected to the hopper: - cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ); - if (Chest == NULL) + cChestEntity * ConnectedChest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ); + if (ConnectedChest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ); return false; } - if (MoveItemsToGrid(*Chest)) + if (MoveItemsToGrid(*ConnectedChest)) { // Chest block directly connected was not full return true; @@ -586,13 +586,13 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block } BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z); - if (Block != Chest->GetBlockType()) + if (Block != ConnectedChest->GetBlockType()) { // Not the same kind of chest continue; } - Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z); + cChestEntity * Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z); if (Chest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z); -- cgit v1.2.3 From df96f437a3802ffeb36c1fefca3d2674bbb94079 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 22:15:52 +0100 Subject: Fixed circular dependecy luaState_Call.inc --- src/Bindings/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index a2b381a26..54152668a 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -45,7 +45,6 @@ set(BINDING_DEPENDENCIES ../Bindings/AllToLua.pkg ../Bindings/gen_LuaState_Call.lua ../Bindings/LuaFunctions.h - ../Bindings/LuaState_Call.inc ../Bindings/LuaWindow.h ../Bindings/Plugin.h ../Bindings/PluginLua.h @@ -128,6 +127,7 @@ if (NOT MSVC) endif () set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE) +set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE) if(NOT MSVC) add_library(Bindings ${SRCS} ${HDRS}) -- cgit v1.2.3 From dba672361164dc5dc5f94d24bde3176c7de89d4c Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 2 Aug 2014 22:42:53 -0700 Subject: Player.cpp: change unnamed enum to constant integers --- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 608316e9a..91bcddca3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -509,7 +509,7 @@ void cPlayer::Heal(int a_Health) void cPlayer::SetFoodLevel(int a_FoodLevel) { - int FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL)); + int FoodLevel = Clamp(a_FoodLevel, 0, MAX_FOOD_LEVEL); if (cRoot::Get()->GetPluginManager()->CallHookPlayerFoodLevelChange(*this, FoodLevel)) { diff --git a/src/Entities/Player.h b/src/Entities/Player.h index e26808bfc..f345a0207 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -29,12 +29,13 @@ class cPlayer : typedef cPawn super; public: - enum - { - MAX_HEALTH = 20, - MAX_FOOD_LEVEL = 20, - EATING_TICKS = 30, ///< Number of ticks it takes to eat an item - } ; + static const int MAX_HEALTH = 20; + + static const int MAX_FOOD_LEVEL = 20; + + /** Number of ticks it takes to eat an item */ + static const int EATING_TICKS = 30; + // tolua_end CLASS_PROTODEF(cPlayer) -- cgit v1.2.3 From 92f67789fc24572092a70d582aef22d7ef1dd272 Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 2 Aug 2014 22:56:08 -0700 Subject: Gave names to unnamed enums --- src/Enchantments.h | 2 +- src/HTTPServer/HTTPMessage.h | 2 +- src/Inventory.h | 4 ++-- src/Protocol/Protocol125.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Enchantments.h b/src/Enchantments.h index 98d7c0d36..824f6aa55 100644 --- a/src/Enchantments.h +++ b/src/Enchantments.h @@ -43,7 +43,7 @@ public: /** Individual enchantment IDs, corresponding to their NBT IDs: http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs */ - enum + enum eEnchantment { enchProtection = 0, enchFireProtection = 1, diff --git a/src/HTTPServer/HTTPMessage.h b/src/HTTPServer/HTTPMessage.h index e402c8ad6..c0667030f 100644 --- a/src/HTTPServer/HTTPMessage.h +++ b/src/HTTPServer/HTTPMessage.h @@ -18,7 +18,7 @@ class cHTTPMessage { public: - enum + enum eStatus { HTTP_OK = 200, HTTP_BAD_REQUEST = 400, diff --git a/src/Inventory.h b/src/Inventory.h index ed134aee4..5628fb0da 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -39,8 +39,8 @@ public: enum { invArmorCount = 4, - invInventoryCount = 9 * 3, - invHotbarCount = 9, + invInventoryCount = 9 * 3, + invHotbarCount = 9, invArmorOffset = 0, invInventoryOffset = invArmorOffset + invArmorCount, diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 18efeb079..3adac3055 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -103,7 +103,7 @@ public: protected: /// Results of packet-parsing: - enum + enum eParseResult { PARSE_OK = 1, PARSE_ERROR = -1, -- cgit v1.2.3 From 47c928cab7d1ff73e50925bc7ef50586b6ec9821 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 11 Aug 2014 00:20:28 +0200 Subject: Exported daylight cycle flag to the protocol. --- src/ClientHandle.cpp | 12 +++--------- src/ClientHandle.h | 2 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 5 ++++- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol14x.cpp | 8 +++++++- src/Protocol/Protocol14x.h | 2 +- src/Protocol/Protocol17x.cpp | 7 ++++++- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 9 +-------- 12 files changed, 29 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 37d7edbc1..d386f3576 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -342,13 +342,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, } // Send time: - Int64 TimeOfDay = World->GetTimeOfDay(); - if (!World->IsDaylightCycleEnabled()) - { - // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. - TimeOfDay = std::min(-TimeOfDay, -1); - } - m_Protocol->SendTimeUpdate(World->GetWorldAge(), TimeOfDay); + m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay(), World->IsDaylightCycleEnabled()); // Send contents of the inventory window m_Protocol->SendWholeInventory(*m_Player->GetWindow()); @@ -2595,9 +2589,9 @@ void cClientHandle::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { - m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay); + m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 1bf397ad2..7ae70a07f 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -179,7 +179,7 @@ public: void SendTabCompletionResults(const AStringVector & a_Results); void SendTeleportEntity (const cEntity & a_Entity); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); - void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); // tolua_export + void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index d110f2af9..8e1842ec1 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -116,7 +116,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 538d31642..a66c64309 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1072,8 +1072,11 @@ void cProtocol125::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { + // This protocol doesn't support a_DoDaylightCycle on false. + UNUSED(a_DoDaylightCycle); + cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_TIME); // Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day: diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 18efeb079..0973bb005 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -88,7 +88,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {} virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp index 8b177ea48..3b6b6a42a 100644 --- a/src/Protocol/Protocol14x.cpp +++ b/src/Protocol/Protocol14x.cpp @@ -130,8 +130,14 @@ void cProtocol142::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src -void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } + cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_TIME); WriteInt64(a_WorldAge); diff --git a/src/Protocol/Protocol14x.h b/src/Protocol/Protocol14x.h index ca497bbc1..227cc8cc7 100644 --- a/src/Protocol/Protocol14x.h +++ b/src/Protocol/Protocol14x.h @@ -34,7 +34,7 @@ public: // Sending commands (alphabetically sorted): virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; // Specific packet parsers: virtual int ParseLocaleViewDistance(void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 318342f09..a724133fc 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1286,9 +1286,14 @@ void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } cPacketizer Pkt(*this, 0x03); Pkt.WriteInt64(a_WorldAge); diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 9c9f563e0..ccfa19eb6 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -120,7 +120,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index a7fb7bcc2..18694572a 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -716,10 +716,10 @@ void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_Bloc -void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { ASSERT(m_Protocol != NULL); - m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay); + m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 65829ef73..28572a8fd 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -123,7 +123,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/World.cpp b/src/World.cpp index dcca0519e..5298f3b03 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2250,13 +2250,6 @@ void cWorld::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { - int TimeOfDay = m_TimeOfDay; - if (!m_IsDaylightCycleEnabled) - { - // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. - TimeOfDay = std::min(-TimeOfDay, -1); - } - cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { @@ -2265,7 +2258,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { continue; } - ch->SendTimeUpdate(m_WorldAge, TimeOfDay); + ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay, m_IsDaylightCycleEnabled); } } -- cgit v1.2.3 From a7eb4032ee32f8299857ccdfc4ad9f45227abb05 Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 10 Aug 2014 17:13:14 -0700 Subject: Fixed tolua error with static initialization --- src/Entities/Player.cpp | 9 +++++++++ src/Entities/Player.h | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 91bcddca3..4398a5bf3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -33,6 +33,15 @@ +const int cPlayer::MAX_HEALTH = 20; + +const int cPlayer::MAX_FOOD_LEVEL = 20; + +/** Number of ticks it takes to eat an item */ +const int cPlayer::EATING_TICKS = 30; + + + cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : diff --git a/src/Entities/Player.h b/src/Entities/Player.h index f345a0207..d3ed1ef9d 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -29,12 +29,12 @@ class cPlayer : typedef cPawn super; public: - static const int MAX_HEALTH = 20; + static const int MAX_HEALTH; - static const int MAX_FOOD_LEVEL = 20; + static const int MAX_FOOD_LEVEL; /** Number of ticks it takes to eat an item */ - static const int EATING_TICKS = 30; + static const int EATING_TICKS; // tolua_end -- cgit v1.2.3 From 202a0d1c1d6de6cc1b229026d0304a736a1d9b75 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 11 Aug 2014 14:24:36 +0200 Subject: Fixed cancelled fire interact from all directions. --- src/ClientHandle.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3e046f38d..8eff45cf4 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -920,9 +920,13 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB ) { m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + if (a_BlockFace != BLOCK_FACE_NONE) { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + } } return; } @@ -932,9 +936,13 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB { // A plugin doesn't agree with the action, replace the block on the client and quit: m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough()) + if (a_BlockFace != BLOCK_FACE_NONE) { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ))->IsClickedThrough()) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + } } return; } -- cgit v1.2.3 From 0a52ed6eb97ca5cc08fe255bfd04f78b4ea19a7e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 11 Aug 2014 15:33:20 +0200 Subject: cProtocol172: Check return values. Fixes CID 43489, CID 43490, CID 43491, CID 43493, CID 66410, CID 66411, CID 66416, CID 66417, CID 66418, CID 66419, CID 66420, CID 66421, CID 66422, CID 66423, CID 66424, CID 66425, CID 66429, CID 66430, CID 66431 --- src/Protocol/Protocol17x.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 318342f09..1f8ca00bb 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -48,7 +48,10 @@ Implements the 1.7.x protocol classes: #define HANDLE_READ(ByteBuf, Proc, Type, Var) \ Type Var; \ - ByteBuf.Proc(Var); + if (!ByteBuf.Proc(Var))\ + {\ + return;\ + } @@ -1700,8 +1703,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) { - Int64 Timestamp; - a_ByteBuffer.ReadBEInt64(Timestamp); + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp); cPacketizer Pkt(*this, 0x01); // Ping packet Pkt.WriteInt64(Timestamp); @@ -2054,7 +2056,10 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length); AString Data; - a_ByteBuffer.ReadString(Data, Length); + if (!a_ByteBuffer.ReadString(Data, Length)) + { + return; + } m_Client->HandlePluginMessage(Channel, Data); } -- cgit v1.2.3 From e0b45c189328d668f5177e529abe99387fc49cf3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 11 Aug 2014 16:06:40 +0200 Subject: Fixed unchecked return values. --- src/Bindings/ManualBindings_RankManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index d17672dcb..b109b0097 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -57,8 +57,8 @@ static int tolua_cRankManager_AddGroupToRank(lua_State * L) S.GetStackValues(2, GroupName, RankName); // Add the group to the rank: - cRoot::Get()->GetRankManager().AddGroupToRank(GroupName, RankName); - return 0; + S.Push(cRoot::Get()->GetRankManager().AddGroupToRank(GroupName, RankName)); + return 1; } @@ -287,7 +287,10 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) // Get the permissions: AString MsgPrefix, MsgSuffix, MsgNameColorCode; - cRoot::Get()->GetRankManager().GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode); + if (!cRoot::Get()->GetRankManager().GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode)) + { + return 0; + } // Push the results: S.Push(MsgPrefix); -- cgit v1.2.3 From 74fabb079c710ab9f81e0b7ee30a8a3e3604595c Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 11 Aug 2014 22:34:33 +0200 Subject: Moved the clicked-through block check to the top of the function. --- src/Blocks/BlockFire.h | 5 ----- src/ClientHandle.cpp | 53 ++++++++++++++++---------------------------------- 2 files changed, 17 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index f52825362..df50d5962 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -40,11 +40,6 @@ public: FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface); } - virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - } - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // No pickups from this block diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8eff45cf4..f09e9531d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -912,6 +912,23 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB return; } + // Check for clickthrough-blocks: + /* When the user breaks a fire block, the client send the wrong block location. + We must find the right block with the face direction. */ + if (a_BlockFace != BLOCK_FACE_NONE) + { + int BlockX = a_BlockX; + int BlockY = a_BlockY; + int BlockZ = a_BlockZ; + AddFaceDirection(BlockX, BlockY, BlockZ, a_BlockFace); + if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(BlockX, BlockY, BlockZ))->IsClickedThrough()) + { + a_BlockX = BlockX; + a_BlockY = BlockY; + a_BlockZ = BlockZ; + } + } + if ( ((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) && // Only do a radius check for block destruction - things like pickup tossing send coordinates that are to be ignored ((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || @@ -920,14 +937,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB ) { m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - if (a_BlockFace != BLOCK_FACE_NONE) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ))->IsClickedThrough()) - { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - } - } return; } @@ -936,14 +945,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB { // A plugin doesn't agree with the action, replace the block on the client and quit: m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - if (a_BlockFace != BLOCK_FACE_NONE) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ))->IsClickedThrough()) - { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - } - } return; } @@ -1067,26 +1068,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc m_LastDigBlockY = a_BlockY; m_LastDigBlockZ = a_BlockZ; - // Check for clickthrough-blocks: - /* When the user breaks a fire block, the client send the wrong block location. - We must find the right block with the face direction. */ - if (a_BlockFace != BLOCK_FACE_NONE) - { - int pX = a_BlockX; - int pY = a_BlockY; - int pZ = a_BlockZ; - - AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false) - cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ)); - - if (Handler->IsClickedThrough()) - { - cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap()); - Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ); - return; - } - } - if ( (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too -- cgit v1.2.3 From 01001d2a49a3366e9b1eccf938d5073ab9a2f06e Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 11 Aug 2014 22:37:28 +0200 Subject: Removes the fire if the block under the fire was broken. --- src/ClientHandle.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f09e9531d..4b5c52c8c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1143,6 +1143,11 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo World->BroadcastSoundParticleEffect(2001, a_BlockX, a_BlockY, a_BlockZ, a_OldBlock, this); World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); + if (World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == E_BLOCK_FIRE) + { + World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0); + } + cRoot::Get()->GetPluginManager()->CallHookPlayerBrokenBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta); } -- cgit v1.2.3 From cb980145820b1bb016dac17a28731cc0b600442a Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 11 Aug 2014 23:12:32 +0200 Subject: Revert "Removes the fire if the block under the fire was broken." This reverts commit 01001d2a49a3366e9b1eccf938d5073ab9a2f06e. --- src/ClientHandle.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 4b5c52c8c..f09e9531d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1143,11 +1143,6 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo World->BroadcastSoundParticleEffect(2001, a_BlockX, a_BlockY, a_BlockZ, a_OldBlock, this); World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); - if (World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == E_BLOCK_FIRE) - { - World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0); - } - cRoot::Get()->GetPluginManager()->CallHookPlayerBrokenBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta); } -- cgit v1.2.3 From 98443682671d0c39b19f86098f7bc900b7529b72 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 12 Aug 2014 16:05:04 +0100 Subject: Renamed Loggers --- src/Bindings/ManualBindings.cpp | 10 +- src/CMakeLists.txt | 7 +- src/CompositeChat.cpp | 24 ++-- src/CompositeChat.h | 2 +- src/Globals.h | 2 +- src/Listeners.cpp | 236 ---------------------------------------- src/Listeners.h | 21 ---- src/LogDispacher.cpp | 114 ------------------- src/LogDispacher.h | 81 -------------- src/Logger.cpp | 109 +++++++++++++++++++ src/Logger.h | 73 +++++++++++++ src/LoggerListeners.cpp | 231 +++++++++++++++++++++++++++++++++++++++ src/LoggerListeners.h | 17 +++ src/Root.cpp | 14 +-- src/main.cpp | 2 +- 15 files changed, 461 insertions(+), 482 deletions(-) delete mode 100644 src/Listeners.cpp delete mode 100644 src/Listeners.h delete mode 100644 src/LogDispacher.cpp delete mode 100644 src/LogDispacher.h create mode 100644 src/Logger.cpp create mode 100644 src/Logger.h create mode 100644 src/LoggerListeners.cpp create mode 100644 src/LoggerListeners.h (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index d792cd0ee..e1e6585f0 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -168,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { // If the param is a cCompositeChat, read the log level from it: - Logger::eLogLevel LogLevel = Logger::llRegular; + cLogger::eLogLevel LogLevel = cLogger::llRegular; tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { @@ -176,7 +176,7 @@ static int tolua_LOG(lua_State * tolua_S) } // Log the message: - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -186,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llInfo); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llInfo); return 0; } @@ -196,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llWarning); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llWarning); return 0; } @@ -206,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llError); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llError); return 0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bca6a2eb0..8925c9be8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,8 +42,8 @@ SET (SRCS LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp - Listeners.cpp - LogDispacher.cpp + LoggerListeners.cpp + Logger.cpp Map.cpp MapManager.cpp MobCensus.cpp @@ -108,7 +108,8 @@ SET (HDRS LineBlockTracer.h LinearInterpolation.h LinearUpscale.h - LogDispacher.h + Logger.h + LoggerListeners.h Map.h MapManager.h Matrix4.h diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index b702447be..0d339021e 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -353,23 +353,23 @@ AString cCompositeChat::ExtractText(void) const -Logger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +cLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) { switch (a_MessageType) { - case mtCustom: return Logger::llRegular; - case mtFailure: return Logger::llWarning; - case mtInformation: return Logger::llInfo; - case mtSuccess: return Logger::llRegular; - case mtWarning: return Logger::llWarning; - case mtFatal: return Logger::llError; - case mtDeath: return Logger::llRegular; - case mtPrivateMessage: return Logger::llRegular; - case mtJoin: return Logger::llRegular; - case mtLeave: return Logger::llRegular; + case mtCustom: return cLogger::llRegular; + case mtFailure: return cLogger::llWarning; + case mtInformation: return cLogger::llInfo; + case mtSuccess: return cLogger::llRegular; + case mtWarning: return cLogger::llWarning; + case mtFatal: return cLogger::llError; + case mtDeath: return cLogger::llRegular; + case mtPrivateMessage: return cLogger::llRegular; + case mtJoin: return cLogger::llRegular; + case mtLeave: return cLogger::llRegular; } ASSERT(!"Unhandled MessageType"); - return Logger::llError; + return cLogger::llError; } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index cc7c446c3..2dc21b98f 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -196,7 +196,7 @@ public: /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ - static Logger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); protected: /** All the parts that */ diff --git a/src/Globals.h b/src/Globals.h index ae7a68e7f..de1024010 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -249,7 +249,7 @@ template class SizeChecker; #include "OSSupport/Event.h" #include "OSSupport/Thread.h" #include "OSSupport/File.h" - #include "LogDispacher.h" + #include "Logger.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/Listeners.cpp b/src/Listeners.cpp deleted file mode 100644 index 384dcaf91..000000000 --- a/src/Listeners.cpp +++ /dev/null @@ -1,236 +0,0 @@ - -#include "Globals.h" - -#include "Listeners.h" - -#if defined(_WIN32) - #include // Needed for _isatty(), not available on Linux -#elif defined(__linux) && !defined(ANDROID_NDK) - #include // Needed for isatty() on Linux -#elif defined(ANDROID_NDK) - #include -#endif - - -namespace Logger -{ - - #if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) - class cColouredConsoleListener - : public cLoggerListener - { - - virtual void SetLogColour(eLogLevel a_LogLevel) = 0; - virtual void SetDefaultLogColour() = 0; - - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - SetLogColour(a_LogLevel); - puts(a_Message.c_str()); - SetDefaultLogColour(); - } - }; - #endif - - #ifdef _WIN32 - class cWindowsConsoleListener - : public cColouredConsoleListener - { - public: - cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : - m_Console(a_Console), - m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) - { - } - - #ifdef DEBUG - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - cColouredConsoleListener::Log(a_Message, a_LogLevel); - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA(a_Message.c_str()); - } - #endif // _WIN32 - - - virtual void SetLogColour(eLogLevel a_LogLevel) override - { - // by default, gray on black - WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - switch (a_LogLevel) - { - case llRegular: - // Gray on black - Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - break; - case llInfo: - // Yellow on black - Attrib = FOREGROUND_GREEN | ; - break; - case llWarning: - // Red on black - Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case llError: - // Black on red - Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; - break; - } - SetConsoleTextAttribute(m_Console, Attrib); - } - virtual void SetDefaultLogColour() override - { - SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); - } - private: - HANDLE m_Console; - WORD m_DefaultConsoleAttrib; - }; - #elif defined (__linux) && !defined(ANDROID_NDK) - class cLinuxConsoleListener - : public cColouredConsoleListener - { - public: - virtual void SetLogColour(eLogLevel a_LogLevel) override - { - switch (a_LogLevel) - { - case llRegular: - // Whatever the console default is - printf("\x1b[0m"); - break; - case llInfo: - // Yellow on black - printf("\x1b[33;1m"); - break; - case llWarning: - // Red on black - printf("\x1b[31;1m"); - break; - case llError: - // Yellow on red - printf("\x1b[1;33;41;1m"); - break; - } - } - virtual void SetDefaultLogColour() override - { - // Whatever the console default is - printf("\x1b[0m"); - } - }; - #elif defined(ANDROID_NDK) - class cAndroidConsoleListener - : public cLoggerListener - { - public: - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - android_LogPriority AndroidLogLevel; - switch (a_LogLevel) - { - case llRegular: - AndroidLogLevel = ANDROID_LOG_VERBOSE; - break; - case llInfo: - AndroidLogLevel = ANDROID_LOG_INFO; - break; - case llWarning: - AndroidLogLevel = ANDROID_LOG_WARNING; - break; - case llError: - AndroidLogLevel = ANDROID_LOG_ERROR; - break; - } - __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); - } - }; - #endif - - class cVanillaCPPConsoleListener - : public cLoggerListener - { - public: - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - AString LogLevelString; - switch (a_LogLevel) - { - case llRegular: - LogLevelString = "Log"; - break; - case llInfo: - LogLevelString = "Info"; - break; - case llWarning: - LogLevelString = "Warning"; - break; - case llError: - LogLevelString = "Error"; - break; - } - printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); - } - }; - - - - cLoggerListener * MakeConsoleListener() - { - #ifdef _WIN32 - // See whether we are writing to a console the default console attrib: - bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); - if (ShouldColorOutput) - { - CONSOLE_SCREEN_BUFFER_INFO sbi; - HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(Console, &sbi); - WORD DefaultConsoleAttrib = sbi.wAttributes; - return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); - } else { - return new cVanillaCPPConsoleListener(); - } - - #elif defined (__linux) && !defined(ANDROID_NDK) - // TODO: lookup terminal in terminfo - if (isatty(fileno(stdout))) - { - return new cLinuxConsoleListener(); - } else { - return new cVanillaCPPConsoleListener(); - } - #else - return new cVanillaCPPConsoleListener(); - #endif - } - - cFileListener::cFileListener() - { - cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); - AString FileName; - FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); - m_File.Open(FileName, cFile::fmAppend); - } - - void cFileListener::Log(AString a_Message, eLogLevel a_LogLevel) - { - AString LogLevelString; - switch (a_LogLevel) - { - case llRegular: - LogLevelString = "Log"; - break; - case llInfo: - LogLevelString = "Info"; - break; - case llWarning: - LogLevelString = "Warning"; - break; - case llError: - LogLevelString = "Error"; - break; - } - m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); - } - -} diff --git a/src/Listeners.h b/src/Listeners.h deleted file mode 100644 index bc29d0c06..000000000 --- a/src/Listeners.h +++ /dev/null @@ -1,21 +0,0 @@ - -#include "LogDispacher.h" - -namespace Logger -{ - - class cFileListener - : public cLoggerListener - { - public: - - cFileListener(); - cFileListener(AString a_Filename); - - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override; - private: - cFile m_File; - }; - - cLoggerListener * MakeConsoleListener(); -} diff --git a/src/LogDispacher.cpp b/src/LogDispacher.cpp deleted file mode 100644 index abca6a898..000000000 --- a/src/LogDispacher.cpp +++ /dev/null @@ -1,114 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "OSSupport/IsThread.h" - - - -namespace Logger -{ - - cLogDispacher & GetInstance(void) - { - static cLogDispacher Instance; - return Instance; - } - - void InitiateMultithreading() - { - GetInstance(); - } - - void cLogDispacher::LogSimple(AString a_Message, eLogLevel a_LogLevel) - { - time_t rawtime; - time ( &rawtime); - - struct tm* timeinfo; - #ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); - #else - timeinfo = localtime( &rawtime); - #endif - - AString Line; - #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); - #endif - - - cCSLock Lock(m_CriticalSection); - for(size_t i = 0; i < m_LogListeners.size(); i++) - { - m_LogListeners[i]->Log(a_Message, a_LogLevel); - } - } - - - - - - void cLogDispacher::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) - { - AString Message; - AppendVPrintf(Message, a_Format, a_ArgList); - LogSimple(Message, a_LogLevel); - } - - void cLogDispacher::AttachListener(Logger::cLoggerListener * a_Listener) - { - cCSLock Lock(m_CriticalSection); - m_LogListeners.push_back(a_Listener); - } - - void cLogDispacher::DetachListener(Logger::cLoggerListener * a_Listener) - { - cCSLock Lock(m_CriticalSection); - m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); - } -}; - - - -//////////////////////////////////////////////////////////////////////////////// -// Global functions - -void LOG(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log(a_Format, Logger::llRegular, argList); - va_end(argList); -} - -void LOGINFO(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llInfo, argList); - va_end(argList); -} - -void LOGWARN(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llWarning, argList); - va_end(argList); -} - -void LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llError, argList); - va_end(argList); -} - - - - diff --git a/src/LogDispacher.h b/src/LogDispacher.h deleted file mode 100644 index 1472b392a..000000000 --- a/src/LogDispacher.h +++ /dev/null @@ -1,81 +0,0 @@ - -#pragma once - - -namespace Logger -{ - - enum eLogLevel - { - llRegular, - llInfo, - llWarning, - llError, - }; - - class cLogDispacher; - - // Must be called before calling GetInstance in a multithreaded context - void InitiateMultithreading(); - - cLogDispacher & GetInstance(void); - - class cLoggerListener - { - public: - virtual void Log(AString a_Message, eLogLevel a_LogLevel) = 0; - - virtual ~cLoggerListener(){} - }; - - class cLogDispacher - { - public: - - void Log (const char * a_Format, Logger::eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); - - /** Logs the simple text message at the specified log level. */ - void LogSimple(AString a_Message, Logger::eLogLevel a_LogLevel = Logger::llRegular); - - void AttachListener(Logger::cLoggerListener * a_Listener); - void DetachListener(Logger::cLoggerListener * a_Listener); - - private: - - cCriticalSection m_CriticalSection; - std::vector m_LogListeners; - - }; - -} - - - - - - -extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); - - - - - -// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: -#ifdef _DEBUG - #define LOGD LOG -#else - #define LOGD(...) -#endif // _DEBUG - - - - - -#define LOGWARNING LOGWARN - - - - diff --git a/src/Logger.cpp b/src/Logger.cpp new file mode 100644 index 000000000..e0ea973f8 --- /dev/null +++ b/src/Logger.cpp @@ -0,0 +1,109 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "OSSupport/IsThread.h" + + +cLogger & cLogger::GetInstance(void) +{ + static cLogger Instance; + return Instance; +} + +void cLogger::InitiateMultithreading() +{ + GetInstance(); +} + +void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) +{ + time_t rawtime; + time ( &rawtime); + + struct tm* timeinfo; + #ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); + #else + timeinfo = localtime( &rawtime); + #endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #endif + + + cCSLock Lock(m_CriticalSection); + for(size_t i = 0; i < m_LogListeners.size(); i++) + { + m_LogListeners[i]->Log(a_Message, a_LogLevel); + } +} + + + + + +void cLogger::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) +{ + AString Message; + AppendVPrintf(Message, a_Format, a_ArgList); + LogSimple(Message, a_LogLevel); +} + +void cLogger::AttachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.push_back(a_Listener); +} + +void cLogger::DetachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Global functions + +void LOG(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log(a_Format, cLogger::llRegular, argList); + va_end(argList); +} + +void LOGINFO(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llInfo, argList); + va_end(argList); +} + +void LOGWARN(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llWarning, argList); + va_end(argList); +} + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llError, argList); + va_end(argList); +} + + + + diff --git a/src/Logger.h b/src/Logger.h new file mode 100644 index 000000000..5e65de8a8 --- /dev/null +++ b/src/Logger.h @@ -0,0 +1,73 @@ + +#pragma once + + +class cLogger +{ +public: + + enum eLogLevel + { + llRegular, + llInfo, + llWarning, + llError, + }; + + + class cListener + { + public: + virtual void Log(AString a_Message, eLogLevel a_LogLevel) = 0; + + virtual ~cListener(){} + }; + + void Log (const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); + + /** Logs the simple text message at the specified log level. */ + void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular); + + void AttachListener(cListener * a_Listener); + void DetachListener(cListener * a_Listener); + + static cLogger & GetInstance(void); + // Must be called before calling GetInstance in a multithreaded context + static void InitiateMultithreading(); +private: + + cCriticalSection m_CriticalSection; + std::vector m_LogListeners; + +}; + + + + + + +extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); + + + + + +// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: +#ifdef _DEBUG + #define LOGD LOG +#else + #define LOGD(...) +#endif // _DEBUG + + + + + +#define LOGWARNING LOGWARN + + + + diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp new file mode 100644 index 000000000..d6567abe0 --- /dev/null +++ b/src/LoggerListeners.cpp @@ -0,0 +1,231 @@ + +#include "Globals.h" + +#include "LoggerListeners.h" + +#if defined(_WIN32) + #include // Needed for _isatty(), not available on Linux +#elif defined(__linux) && !defined(ANDROID_NDK) + #include // Needed for isatty() on Linux +#elif defined(ANDROID_NDK) + #include +#endif + + +#if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) + class cColouredConsoleListener + : public cLogger::cListener + { + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) = 0; + virtual void SetDefaultLogColour() = 0; + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + SetLogColour(a_LogLevel); + puts(a_Message.c_str()); + SetDefaultLogColour(); + } + }; +#endif + +#ifdef _WIN32 + class cWindowsConsoleListener + : public cColouredConsoleListener + { + public: + cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : + m_Console(a_Console), + m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) + { + } + + #ifdef DEBUG + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + cColouredConsoleListener::Log(a_Message, a_LogLevel); + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA(a_Message.c_str()); + } + #endif + + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + // by default, gray on black + WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + switch (a_LogLevel) + { + case cLogger::llRegular: + // Gray on black + Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + case cLogger::llInfo: + // Yellow on black + Attrib = FOREGROUND_GREEN | ; + break; + case cLogger::llWarning: + // Red on black + Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + case cLogger::llError: + // Black on red + Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; + break; + } + SetConsoleTextAttribute(m_Console, Attrib); + } + virtual void SetDefaultLogColour() override + { + SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); + } + private: + HANDLE m_Console; + WORD m_DefaultConsoleAttrib; + }; +#elif defined (__linux) && !defined(ANDROID_NDK) + class cLinuxConsoleListener + : public cColouredConsoleListener + { + public: + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + switch (a_LogLevel) + { + case cLogger::llRegular: + // Whatever the console default is + printf("\x1b[0m"); + break; + case cLogger::llInfo: + // Yellow on black + printf("\x1b[33;1m"); + break; + case cLogger::llWarning: + // Red on black + printf("\x1b[31;1m"); + break; + case cLogger::llError: + // Yellow on red + printf("\x1b[1;33;41;1m"); + break; + } + } + virtual void SetDefaultLogColour() override + { + // Whatever the console default is + printf("\x1b[0m"); + } + }; +#elif defined(ANDROID_NDK) + class cAndroidConsoleListener + : public cLogger::cListener + { + public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + android_LogPriority AndroidLogLevel; + switch (a_LogLevel) + { + case cLogger::llRegular: + AndroidLogLevel = ANDROID_LOG_VERBOSE; + break; + case cLogger::llInfo: + AndroidLogLevel = ANDROID_LOG_INFO; + break; + case cLogger::llWarning: + AndroidLogLevel = ANDROID_LOG_WARNING; + break; + case cLogger::llError: + AndroidLogLevel = ANDROID_LOG_ERROR; + break; + } + __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); + } + }; +#endif + +class cVanillaCPPConsoleListener + : public cLogger::cListener +{ +public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + AString LogLevelString; + switch (a_LogLevel) + { + case cLogger::llRegular: + LogLevelString = "Log"; + break; + case cLogger::llInfo: + LogLevelString = "Info"; + break; + case cLogger::llWarning: + LogLevelString = "Warning"; + break; + case cLogger::llError: + LogLevelString = "Error"; + break; + } + printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + } +}; + + + +cLogger::cListener * MakeConsoleListener() +{ + #ifdef _WIN32 + // See whether we are writing to a console the default console attrib: + bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); + if (ShouldColorOutput) + { + CONSOLE_SCREEN_BUFFER_INFO sbi; + HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(Console, &sbi); + WORD DefaultConsoleAttrib = sbi.wAttributes; + return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); + } else { + return new cVanillaCPPConsoleListener(); + } + + #elif defined (__linux) && !defined(ANDROID_NDK) + // TODO: lookup terminal in terminfo + if (isatty(fileno(stdout))) + { + return new cLinuxConsoleListener(); + } else { + return new cVanillaCPPConsoleListener(); + } + #else + return new cVanillaCPPConsoleListener(); + #endif +} + +cFileListener::cFileListener() +{ + cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); + AString FileName; + FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); + m_File.Open(FileName, cFile::fmAppend); +} + +void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) +{ + AString LogLevelString; + switch (a_LogLevel) + { + case cLogger::llRegular: + LogLevelString = "Log"; + break; + case cLogger::llInfo: + LogLevelString = "Info"; + break; + case cLogger::llWarning: + LogLevelString = "Warning"; + break; + case cLogger::llError: + LogLevelString = "Error"; + break; + } + m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); +} diff --git a/src/LoggerListeners.h b/src/LoggerListeners.h new file mode 100644 index 000000000..4d2889a93 --- /dev/null +++ b/src/LoggerListeners.h @@ -0,0 +1,17 @@ + +#include "Logger.h" + +class cFileListener + : public cLogger::cListener +{ + public: + + cFileListener(); + cFileListener(AString a_Filename); + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override; + private: + cFile m_File; +}; + +cLogger::cListener * MakeConsoleListener(); diff --git a/src/Root.cpp b/src/Root.cpp index 72048b631..ee0d9b835 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -18,7 +18,7 @@ #include "CommandOutput.h" #include "DeadlockDetect.h" #include "OSSupport/Timer.h" -#include "Listeners.h" +#include "LoggerListeners.h" #include "inifile/iniFile.h" @@ -106,10 +106,10 @@ void cRoot::Start(void) EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif - Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); - Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); - Logger::GetInstance().AttachListener(consoleLogListener); - Logger::GetInstance().AttachListener(fileLogListener); + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); LOG("--- Started Log ---\n"); @@ -257,9 +257,9 @@ void cRoot::Start(void) LOG("--- Stopped Log ---"); - Logger::GetInstance().DetachListener(consoleLogListener); + cLogger::GetInstance().DetachListener(consoleLogListener); delete consoleLogListener; - Logger::GetInstance().DetachListener(fileLogListener); + cLogger::GetInstance().DetachListener(fileLogListener); delete fileLogListener; } diff --git a/src/main.cpp b/src/main.cpp index e40035538..86ecd4000 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,7 +273,7 @@ int main( int argc, char **argv) } } // for i - argv[] - Logger::InitiateMultithreading(); + cLogger::InitiateMultithreading(); #if !defined(ANDROID_NDK) try -- cgit v1.2.3 From 01c50eb53ab06f99fd08a2d599095e6dec683b60 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 12 Aug 2014 17:32:08 +0100 Subject: Fix messing rename --- src/Bindings/LuaFunctions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/LuaFunctions.h b/src/Bindings/LuaFunctions.h index 6a645ed53..be1d9aaa9 100644 --- a/src/Bindings/LuaFunctions.h +++ b/src/Bindings/LuaFunctions.h @@ -1,6 +1,6 @@ #pragma once -#include "LogDispacher.h" +#include "Logger.h" #include // tolua_begin -- cgit v1.2.3 From 10e58f04da038a28626fee90d278c703d55f72b6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 12 Aug 2014 22:43:04 +0200 Subject: Fixed windows compilation and style issues. --- src/Logger.cpp | 56 ++++++++++++++++++---- src/LoggerListeners.cpp | 122 +++++++++++++++++++++++++++++++++++++++++------- src/LoggerListeners.h | 28 ++++++++--- src/OSSupport/File.h | 8 ++-- 4 files changed, 177 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/Logger.cpp b/src/Logger.cpp index e0ea973f8..572a0e160 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -2,6 +2,12 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "OSSupport/IsThread.h" +#ifdef _WIN32 + #include +#endif + + + cLogger & cLogger::GetInstance(void) @@ -10,35 +16,43 @@ cLogger & cLogger::GetInstance(void) return Instance; } + + + + void cLogger::InitiateMultithreading() { GetInstance(); } + + + + void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) { time_t rawtime; - time ( &rawtime); + time(&rawtime); - struct tm* timeinfo; + struct tm * timeinfo; #ifdef _MSC_VER struct tm timeinforeal; timeinfo = &timeinforeal; localtime_s(timeinfo, &rawtime); #else - timeinfo = localtime( &rawtime); + timeinfo = localtime(&rawtime); #endif AString Line; #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #else - Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); #endif cCSLock Lock(m_CriticalSection); - for(size_t i = 0; i < m_LogListeners.size(); i++) + for (size_t i = 0; i < m_LogListeners.size(); i++) { m_LogListeners[i]->Log(a_Message, a_LogLevel); } @@ -55,12 +69,20 @@ void cLogger::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList LogSimple(Message, a_LogLevel); } + + + + void cLogger::AttachListener(cListener * a_Listener) { cCSLock Lock(m_CriticalSection); m_LogListeners.push_back(a_Listener); } + + + + void cLogger::DetachListener(cListener * a_Listener) { cCSLock Lock(m_CriticalSection); @@ -69,10 +91,12 @@ void cLogger::DetachListener(cListener * a_Listener) + + //////////////////////////////////////////////////////////////////////////////// // Global functions -void LOG(const char* a_Format, ...) +void LOG(const char * a_Format, ...) { va_list argList; va_start(argList, a_Format); @@ -80,7 +104,11 @@ void LOG(const char* a_Format, ...) va_end(argList); } -void LOGINFO(const char* a_Format, ...) + + + + +void LOGINFO(const char * a_Format, ...) { va_list argList; va_start(argList, a_Format); @@ -88,7 +116,11 @@ void LOGINFO(const char* a_Format, ...) va_end(argList); } -void LOGWARN(const char* a_Format, ...) + + + + +void LOGWARN(const char * a_Format, ...) { va_list argList; va_start(argList, a_Format); @@ -96,7 +128,11 @@ void LOGWARN(const char* a_Format, ...) va_end(argList); } -void LOGERROR(const char* a_Format, ...) + + + + +void LOGERROR(const char * a_Format, ...) { va_list argList; va_start(argList, a_Format); diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index d6567abe0..912342a65 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -5,6 +5,7 @@ #if defined(_WIN32) #include // Needed for _isatty(), not available on Linux + #include #elif defined(__linux) && !defined(ANDROID_NDK) #include // Needed for isatty() on Linux #elif defined(ANDROID_NDK) @@ -29,10 +30,15 @@ }; #endif + + + + #ifdef _WIN32 class cWindowsConsoleListener : public cColouredConsoleListener { + typedef cColouredConsoleListener super; public: cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : m_Console(a_Console), @@ -43,47 +49,65 @@ #ifdef DEBUG virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override { - cColouredConsoleListener::Log(a_Message, a_LogLevel); + super::Log(a_Message, a_LogLevel); // In a Windows Debug build, output the log to debug console as well: OutputDebugStringA(a_Message.c_str()); } #endif - - + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override { // by default, gray on black - WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; switch (a_LogLevel) { case cLogger::llRegular: + { // Gray on black - Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - break; + Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + } case cLogger::llInfo: + { // Yellow on black - Attrib = FOREGROUND_GREEN | ; - break; + Attrib = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + } case cLogger::llWarning: + { // Red on black Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; + break; + } case cLogger::llError: - // Black on red + { + // Black on red Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; break; + } } SetConsoleTextAttribute(m_Console, Attrib); } + + virtual void SetDefaultLogColour() override { SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); } + private: + HANDLE m_Console; WORD m_DefaultConsoleAttrib; }; + + + #elif defined (__linux) && !defined(ANDROID_NDK) + + + class cLinuxConsoleListener : public cColouredConsoleListener { @@ -93,30 +117,46 @@ switch (a_LogLevel) { case cLogger::llRegular: + { // Whatever the console default is printf("\x1b[0m"); break; + } case cLogger::llInfo: + { // Yellow on black printf("\x1b[33;1m"); break; + } case cLogger::llWarning: + { // Red on black printf("\x1b[31;1m"); break; + } case cLogger::llError: + { // Yellow on red printf("\x1b[1;33;41;1m"); break; + } } } + + virtual void SetDefaultLogColour() override { // Whatever the console default is printf("\x1b[0m"); } }; + + + #elif defined(ANDROID_NDK) + + + class cAndroidConsoleListener : public cLogger::cListener { @@ -127,23 +167,36 @@ switch (a_LogLevel) { case cLogger::llRegular: + { AndroidLogLevel = ANDROID_LOG_VERBOSE; break; + } case cLogger::llInfo: + { AndroidLogLevel = ANDROID_LOG_INFO; break; + } case cLogger::llWarning: + { AndroidLogLevel = ANDROID_LOG_WARNING; break; + } case cLogger::llError: + { AndroidLogLevel = ANDROID_LOG_ERROR; break; + } } __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); } }; + #endif + + + + class cVanillaCPPConsoleListener : public cLogger::cListener { @@ -154,17 +207,25 @@ public: switch (a_LogLevel) { case cLogger::llRegular: + { LogLevelString = "Log"; break; + } case cLogger::llInfo: + { LogLevelString = "Info"; break; + } case cLogger::llWarning: + { LogLevelString = "Warning"; break; + } case cLogger::llError: + { LogLevelString = "Error"; break; + } } printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); } @@ -172,7 +233,9 @@ public: -cLogger::cListener * MakeConsoleListener() + + +cLogger::cListener * MakeConsoleListener(void) { #ifdef _WIN32 // See whether we are writing to a console the default console attrib: @@ -180,12 +243,14 @@ cLogger::cListener * MakeConsoleListener() if (ShouldColorOutput) { CONSOLE_SCREEN_BUFFER_INFO sbi; - HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); + HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(Console, &sbi); WORD DefaultConsoleAttrib = sbi.wAttributes; return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); - } else { - return new cVanillaCPPConsoleListener(); + } + else + { + return new cVanillaCPPConsoleListener; } #elif defined (__linux) && !defined(ANDROID_NDK) @@ -193,7 +258,9 @@ cLogger::cListener * MakeConsoleListener() if (isatty(fileno(stdout))) { return new cLinuxConsoleListener(); - } else { + } + else + { return new cVanillaCPPConsoleListener(); } #else @@ -201,7 +268,14 @@ cLogger::cListener * MakeConsoleListener() #endif } -cFileListener::cFileListener() + + + + +//////////////////////////////////////////////////////////////////////////////// +// cFileListener: + +cFileListener::cFileListener(void) { cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); AString FileName; @@ -209,23 +283,39 @@ cFileListener::cFileListener() m_File.Open(FileName, cFile::fmAppend); } + + + + void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) { AString LogLevelString; switch (a_LogLevel) { case cLogger::llRegular: + { LogLevelString = "Log"; break; + } case cLogger::llInfo: + { LogLevelString = "Info"; break; + } case cLogger::llWarning: + { LogLevelString = "Warning"; break; + } case cLogger::llError: + { LogLevelString = "Error"; break; + } } m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); } + + + + diff --git a/src/LoggerListeners.h b/src/LoggerListeners.h index 4d2889a93..d300184b1 100644 --- a/src/LoggerListeners.h +++ b/src/LoggerListeners.h @@ -1,17 +1,31 @@ #include "Logger.h" + + + + class cFileListener : public cLogger::cListener { - public: - - cFileListener(); - cFileListener(AString a_Filename); +public: + + cFileListener(); + cFileListener(AString a_Filename); + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override; - virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override; - private: - cFile m_File; +private: + + cFile m_File; }; + + + + cLogger::cListener * MakeConsoleListener(); + + + + diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 8891511c4..dfb38e839 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -60,10 +60,10 @@ public: /** The mode in which to open the file */ enum eMode { - fmRead, // Read-only. If the file doesn't exist, object will not be valid - fmWrite, // Write-only. If the file already exists, it will be overwritten - fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning - fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file + fmRead, // Read-only. If the file doesn't exist, object will not be valid + fmWrite, // Write-only. If the file already exists, it will be overwritten + fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file } ; /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ -- cgit v1.2.3 From e110f7226895b1629f72a52c7953d8f00a1f63c6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 13 Aug 2014 09:53:33 +0200 Subject: RankMgr: Initial migration code. --- src/RankManager.cpp | 540 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/RankManager.h | 28 +++ src/Root.cpp | 1 + 3 files changed, 568 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 3627afadb..9809f1d6c 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -6,6 +6,8 @@ #include "Globals.h" #include "RankManager.h" #include "SQLiteCpp/Transaction.h" +#include "inifile/iniFile.h" +#include "Protocol/MojangAPI.h" @@ -219,9 +221,367 @@ protected: +//////////////////////////////////////////////////////////////////////////////// +/** Migrates from groups.ini and users.ini into the rankmanager DB */ +class cRankManagerIniMigrator +{ +public: + cRankManagerIniMigrator(cRankManager & a_RankManager, cMojangAPI & a_MojangAPI) : + m_RankManager(a_RankManager), + m_MojangAPI(a_MojangAPI) + { + } + + + + /** Performs the complete migration from INI files to DB. */ + bool Migrate(void) + { + LOGD("Reading groups..."); + if (!ReadGroups()) + { + return false; + } + LOGD("Cleaning groups inheritance..."); + CleanGroupInheritance(); + LOGD("Creating groups..."); + CreateGroups(); + + LOGD("Reading users..."); + if (!ReadUsers()) + { + return false; + } + LOGD("Cleaning user groups..."); + CleanUserGroups(); + LOGD("Resolving user UUIDs..."); + ResolveUserUUIDs(); + + LOGD("Setting ranks..."); + SetRanks(); + + return true; + } + +protected: + + /** Container for a group read from an INI file. */ + struct sGroup + { + AString m_Name; + AString m_Color; + AStringVector m_Inherits; + AStringVector m_Permissions; + + sGroup(void) {} + + sGroup(const AString & a_Name, const AString & a_Color, const AStringVector & a_Inherits, const AStringVector & a_Permissions): + m_Name(a_Name), + m_Color(a_Color), + m_Inherits(a_Inherits), + m_Permissions(a_Permissions) + { + } + }; + typedef std::map sGroupMap; + + + /** Container for a single user read from an INI file. */ + struct sUser + { + AString m_Name; + AStringVector m_Groups; + + /** Assigned by ResolveUserUUIDs() */ + AString m_UUID; + + + sUser(void) {} + + sUser(const AString & a_Name, const AStringVector & a_Groups): + m_Name(a_Name), + m_Groups(a_Groups) + { + } + }; + typedef std::map sUserMap; + + typedef std::map cStringMap; + + + /** The parent Rank manager where we will create the groups, ranks and players */ + cRankManager & m_RankManager; + + /** The player name to UUID resolver */ + cMojangAPI & m_MojangAPI; + + /** List of all groups read from the ini file */ + sGroupMap m_Groups; + + /** List of all players read from the ini file. */ + sUserMap m_Users; + + /** Maps lists of groups to rank names. + Each group list is either a simple "" if there's only one group, + or ",,...", where the secondary groups are + lowercased and alpha-sorted. This makes the group lists comparable for equivalence, simply by comparing + their string names. + The ranks are named "" for single-group players, and "AutoMigratedRank_N" for the composite ranks, + where N is a unique number. */ + cStringMap m_GroupsToRanks; + + + + /** Reads the groups from the "groups.ini" file into m_Groups */ + bool ReadGroups(void) + { + // Read the file: + cIniFile Groups; + if (!Groups.ReadFile("groups.ini")) + { + return false; + } + + // Read all the groups into a map: + int NumGroups = Groups.GetNumKeys(); + for (int i = 0; i < NumGroups; i++) + { + AString GroupName = Groups.GetKeyName(i); + AString lcGroupName = StrToLower(GroupName); + if (m_Groups.find(lcGroupName) != m_Groups.end()) + { + LOGINFO("groups.ini contains a duplicate definition of group %s, ignoring the latter.", GroupName.c_str()); + continue; + } + m_Groups[lcGroupName] = sGroup( + GroupName, + Groups.GetValue(GroupName, "Color", ""), + StringSplitAndTrim(Groups.GetValue(GroupName, "Inherits"), ","), + StringSplitAndTrim(Groups.GetValue(GroupName, "Permissions"), ",") + ); + } // for i - Groups' keys + return true; + } + + + + /** Removes non-existent groups from all the groups' inheritance */ + void CleanGroupInheritance(void) + { + for (sGroupMap::iterator itrG = m_Groups.begin(), endG = m_Groups.end(); itrG != endG; ++itrG) + { + AStringVector & Inherits = itrG->second.m_Inherits; + for (AStringVector::iterator itrI = Inherits.begin(); itrI != Inherits.end();) + { + AString lcInherits = StrToLower(*itrI); + if (m_Groups.find(lcInherits) != m_Groups.end()) + { + // Inherited group exists, continue checking the next one + ++itrI; + continue; + } + // Inherited group doesn't exist, remove it from the list: + LOGWARNING("RankMigrator: Group \"%s\" inherits from a non-existent group \"%s\", this inheritance will be ignored.", + itrG->second.m_Name.c_str(), itrI->c_str() + ); + AStringVector::iterator itrI2 = itrI; + ++itrI2; + Inherits.erase(itrI); + itrI = itrI2; + } // for itrI - Inherits[] + } // for itrG - m_Groups[] + } + + + + /** Reads the users from the "users.ini" file into m_Users */ + bool ReadUsers(void) + { + // Read the file: + cIniFile Users; + if (!Users.ReadFile("users.ini")) + { + return false; + } + + // Read all the users into a map: + int NumUsers = Users.GetNumKeys(); + for (int i = 0; i < NumUsers; i++) + { + AString UserName = Users.GetKeyName(i); + AString lcUserName = StrToLower(UserName); + if (m_Users.find(lcUserName) != m_Users.end()) + { + LOGINFO("users.ini contains a duplicate definition of user %s, ignoring the latter.", UserName.c_str()); + continue; + } + m_Users[lcUserName] = sUser( + UserName, + StringSplitAndTrim(Users.GetValue(UserName, "Groups", ""), ",") + ); + } // for i - Users' keys + return true; + } + + + + /** Removes non-existent groups from each user's definition. */ + void CleanUserGroups(void) + { + for (sUserMap::iterator itrU = m_Users.begin(), endU = m_Users.end(); itrU != endU; ++itrU) + { + AStringVector & Groups = itrU->second.m_Groups; + for (AStringVector::iterator itrG = Groups.begin(); itrG != Groups.end();) + { + AString lcGroup = StrToLower(*itrG); + if (m_Groups.find(lcGroup) != m_Groups.end()) + { + // Assigned group exists, continue checking the next one + ++itrG; + continue; + } + // Assigned group doesn't exist, remove it from the list: + LOGWARNING("RankMigrator: User \"%s\" is assigned a non-existent group \"%s\", this assignment will be ignored.", + itrU->second.m_Name.c_str(), itrG->c_str() + ); + AStringVector::iterator itrG2 = itrG; + ++itrG2; + Groups.erase(itrG); + itrG = itrG2; + } // for itrG - Groups[] + } // for itrU - m_Users[] + } + + + + /** Creates groups based on m_Groups. + Ignores group inheritance. */ + void CreateGroups(void) + { + // Create each group, with its permissions: + for (sGroupMap::const_iterator itr = m_Groups.begin(), end = m_Groups.end(); itr != end; ++itr) + { + m_RankManager.AddGroup(itr->second.m_Name); + m_RankManager.AddPermissionsToGroup(itr->second.m_Permissions, itr->second.m_Name); + } // for itr - m_Groups[] + } + + + /** Resolves the UUID of each user in m_Users. + If a user doesn't resolve, they are removed and logged in the console. */ + void ResolveUserUUIDs(void) + { + // Resolve all PlayerNames at once (the API doesn't like single-name queries): + AStringVector PlayerNames; + for (sUserMap::const_iterator itr = m_Users.begin(), end = m_Users.end(); itr != end; ++itr) + { + PlayerNames.push_back(itr->second.m_Name); + } + m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames); + + // Assign the UUIDs back to players, remove those not resolved: + for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ) + { + AString UUID = m_MojangAPI.GetUUIDFromPlayerName(itr->second.m_Name); + if (UUID.empty()) + { + LOGWARNING("RankMigrator: Cannot resolve player %s to UUID, player will be left unranked", itr->second.m_Name.c_str()); + sUserMap::iterator itr2 = itr; + ++itr2; + m_Users.erase(itr); + itr = itr2; + } + else + { + itr->second.m_UUID = UUID; + ++itr; + } + } + } + + + + /** Adds the specified groups to the specified ranks. Recurses on the groups' inheritance. */ + void AddGroupsToRank(const AStringVector & a_Groups, const AString & a_RankName) + { + for (AStringVector::const_iterator itr = a_Groups.begin(), end = a_Groups.end(); itr != end; ++itr) + { + // Normalize the group name: + sGroup & Group = m_Groups[StrToLower(*itr)]; + + // Avoid loops, check if the group is already added: + if (m_RankManager.IsGroupInRank(Group.m_Name, a_RankName)) + { + continue; + } + + // Add the group, and all the groups it inherits from recursively: + m_RankManager.AddGroupToRank(Group.m_Name, a_RankName); + AddGroupsToRank(Group.m_Inherits, a_RankName); + } // for itr - a_Groups[] + } + + + + /** Creates a rank for each player, based on the master groups they are assigned. */ + void SetRanks(void) + { + for (sUserMap::const_iterator itr = m_Users.begin(), end = m_Users.end(); itr != end; ++itr) + { + // Ignore users with no groups: + const AStringVector & Groups = itr->second.m_Groups; + if (Groups.empty()) + { + LOGWARNING("RankMigrator: Player %s has no groups assigned to them, skipping the player.", itr->second.m_Name.c_str()); + continue; + } + + // Compose the rank name out of group names: + AString RankName; + for (AStringVector::const_iterator itrG = Groups.begin(), endG = Groups.end(); itrG != endG; ++itrG) + { + AString GroupName = m_Groups[StrToLower(*itrG)].m_Name; // Normalize group name + if (!RankName.empty()) + { + RankName.push_back(','); + } + RankName.append(GroupName); + } // for itrG - Groups[] + + // Create the rank, with al its groups: + if (!m_RankManager.RankExists(RankName)) + { + m_RankManager.AddRank(RankName, "", "", m_Groups[StrToLower(Groups[0])].m_Color); + AddGroupsToRank(Groups, RankName); + } + + // Set the rank to the user: + m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName); + } // for itr - m_Users[] + } +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cRankManager: + cRankManager::cRankManager(void) : - m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) + m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE), + m_IsInitialized(false) +{ +} + + + + + +void cRankManager::Initialize(cMojangAPI & a_MojangAPI) { + ASSERT(!m_IsInitialized); // Calling Initialize for the second time? + // Create the DB tables, if they don't exist: m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgSuffix, MsgNameColorCode)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID INTEGER)"); @@ -229,6 +589,22 @@ cRankManager::cRankManager(void) : m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermGroup (RankID INTEGER, PermGroupID INTEGER)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (PermGroupID INTEGER, Permission)"); + m_IsInitialized = true; + + // Check if tables empty, migrate from ini files then + if (AreDBTablesEmpty()) + { + LOGINFO("There are no ranks, migrating old-style INI files to new DB ranks..."); + LOGINFO("(This might take a while)"); + cRankManagerIniMigrator Migrator(*this, a_MojangAPI); + if (Migrator.Migrate()) + { + LOGINFO("Ranks migrated."); + return; + } + } + + // Migration failed. // TODO: Check if tables empty, add some defaults then } @@ -238,6 +614,8 @@ cRankManager::cRankManager(void) : AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); @@ -263,6 +641,8 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -296,6 +676,8 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -329,6 +711,8 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) AStringVector cRankManager::GetRankGroups(const AString & a_RankName) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -357,6 +741,8 @@ AStringVector cRankManager::GetRankGroups(const AString & a_RankName) AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -384,6 +770,8 @@ AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -412,6 +800,8 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) AStringVector cRankManager::GetAllRanks(void) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -434,6 +824,8 @@ AStringVector cRankManager::GetAllRanks(void) AStringVector cRankManager::GetAllGroups(void) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -456,6 +848,8 @@ AStringVector cRankManager::GetAllGroups(void) AStringVector cRankManager::GetAllPermissions(void) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -483,6 +877,8 @@ bool cRankManager::GetPlayerMsgVisuals( AString & a_MsgNameColorCode ) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -526,6 +922,8 @@ void cRankManager::AddRank( const AString & a_MsgNameColorCode ) { + ASSERT(m_IsInitialized); + try { // Check if such a rank name is already used: @@ -566,6 +964,8 @@ void cRankManager::AddRank( void cRankManager::AddGroup(const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { // Check if such a rank name is already used: @@ -603,6 +1003,8 @@ void cRankManager::AddGroup(const AString & a_GroupName) bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a_RankName) { + ASSERT(m_IsInitialized); + try { SQLite::Transaction trans(m_DB); @@ -680,6 +1082,8 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { // Wrapp the entire operation into a transaction: @@ -746,8 +1150,83 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr +bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + + try + { + // Wrapp the entire operation into a transaction: + SQLite::Transaction trans(m_DB); + + // Get the group's ID: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such group (%s), aborting.", __FUNCTION__, a_GroupName.c_str()); + return false; + } + GroupID = stmt.getColumn(0).getInt(); + } + + for (AStringVector::const_iterator itr = a_Permissions.begin(), end = a_Permissions.end(); itr != end; ++itr) + { + // Check if the permission is already present: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermissionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, *itr); + if (!stmt.executeStep()) + { + LOGWARNING("%s: Failed to check binding between permission %s and group %s, aborting.", __FUNCTION__, itr->c_str(), a_GroupName.c_str()); + return false; + } + if (stmt.getColumn(0).getInt() > 0) + { + LOGD("%s: Permission %s is already present in group %s, skipping and returning success.", + __FUNCTION__, itr->c_str(), a_GroupName.c_str() + ); + continue; + } + } + + // Add the permission: + { + SQLite::Statement stmt(m_DB, "INSERT INTO PermissionItem (Permission, PermGroupID) VALUES (?, ?)"); + stmt.bind(1, *itr); + stmt.bind(2, GroupID); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add permission %s to group %s, skipping.", __FUNCTION__, itr->c_str(), a_GroupName.c_str()); + continue; + } + } + } // for itr - a_Permissions[] + + // Adding succeeded: + trans.commit(); + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add permissions to group %s: %s", + __FUNCTION__, a_GroupName.c_str(), ex.what() + ); + } + return false; +} + + + + + void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName) { + ASSERT(m_IsInitialized); + AStringVector res; try { @@ -823,6 +1302,8 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl void cRankManager::RemoveGroup(const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { // Wrap everything into a transaction: @@ -876,6 +1357,8 @@ void cRankManager::RemoveGroup(const AString & a_GroupName) void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AString & a_RankName) { + ASSERT(m_IsInitialized); + try { // Wrap everything into a transaction: @@ -930,6 +1413,8 @@ void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AStrin void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { // Wrap everything into a transaction: @@ -972,6 +1457,8 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewName) { + ASSERT(m_IsInitialized); + try { // Wrap everything into a transaction: @@ -1014,6 +1501,8 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewName) { + ASSERT(m_IsInitialized); + try { // Wrap everything into a transaction: @@ -1056,6 +1545,8 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName) { + ASSERT(m_IsInitialized); + try { // Wrap the entire operation into a transaction: @@ -1123,6 +1614,8 @@ void cRankManager::SetRankVisuals( const AString & a_MsgNameColorCode ) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "UPDATE Rank SET MsgPrefix = ?, MsgSuffix = ?, MsgNameColorCode = ? WHERE Name = ?"); @@ -1152,6 +1645,8 @@ bool cRankManager::GetRankVisuals( AString & a_MsgNameColorCode ) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "SELECT MsgPrefix, MsgSuffix, MsgNameColorCode FROM Rank WHERE Name = ?"); @@ -1179,6 +1674,8 @@ bool cRankManager::GetRankVisuals( bool cRankManager::RankExists(const AString & a_RankName) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "SELECT * FROM Rank WHERE Name = ?"); @@ -1202,6 +1699,8 @@ bool cRankManager::RankExists(const AString & a_RankName) bool cRankManager::GroupExists(const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "SELECT * FROM PermGroup WHERE Name = ?"); @@ -1225,6 +1724,8 @@ bool cRankManager::GroupExists(const AString & a_GroupName) bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, "SELECT * FROM PlayerRank WHERE PlayerUUID = ?"); @@ -1248,6 +1749,8 @@ bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_RankName) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, @@ -1277,6 +1780,8 @@ bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName) { + ASSERT(m_IsInitialized); + try { SQLite::Statement stmt(m_DB, @@ -1302,3 +1807,36 @@ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AStri + +bool cRankManager::AreDBTablesEmpty(void) +{ + return ( + IsDBTableEmpty("Rank") && + IsDBTableEmpty("PlayerRank") && + IsDBTableEmpty("PermGroup") && + IsDBTableEmpty("RankPermGroup") && + IsDBTableEmpty("PermissionItem") + ); +} + + + + + +bool cRankManager::IsDBTableEmpty(const AString & a_TableName) +{ + try + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM " + a_TableName); + return (stmt.executeStep() && (stmt.getColumn(0).getInt() == 0)); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + diff --git a/src/RankManager.h b/src/RankManager.h index 0a43bfe5d..ffe7638e1 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -14,11 +14,22 @@ +class cMojangAPI; + + + + + class cRankManager { public: + /** Creates the rank manager. Needs to be initialized before other use. */ cRankManager(void); + /** Initializes the rank manager. Performs migration and default-setting if no data is found in the DB. + The a_MojangAPI param is used when migrating from old ini files, to look up player UUIDs. */ + void Initialize(cMojangAPI & a_MojangAPI); + /** Returns the name of the rank that the specified player has assigned to them. */ AString GetPlayerRankName(const AString & a_PlayerUUID); @@ -79,6 +90,11 @@ public: Returns true if successful, false on error. */ bool AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName); + /** Adds the specified permissions to the specified permission group. + Fails if the permission group name is not found. + Returns true if successful, false on error. */ + bool AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName); + /** Removes the specified rank. All players assigned to that rank will be re-assigned to a_ReplacementRankName. If a_ReplacementRankName is empty or not a valid rank, the player will be removed from the DB, @@ -147,7 +163,19 @@ public: protected: + /** The database storage for all the data. */ SQLite::Database m_DB; + + /** Set to true once the manager is initialized. */ + bool m_IsInitialized; + + + /** Returns true if all the DB tables are empty, indicating a fresh new install. */ + bool AreDBTablesEmpty(void); + + /** Returns true iff the specified DB table is empty. + If there's an error while querying, returns false. */ + bool IsDBTableEmpty(const AString & a_TableName); } ; diff --git a/src/Root.cpp b/src/Root.cpp index c20cf0d21..333d92de5 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -156,6 +156,7 @@ void cRoot::Start(void) m_WebAdmin->Init(); LOGD("Loading settings..."); + m_RankManager.Initialize(m_MojangAPI); m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); -- cgit v1.2.3 From 5e415c5b9565564c41c4f2f4144c6863c106bc46 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 13 Aug 2014 12:33:31 +0200 Subject: RankMgr: Fixed multithreading issues. Only one thread is allowed to interact with a SQLite::Database object at a time. Additionally, improved performance of the migration by wrapping the entire thing in a transaction. --- src/RankManager.cpp | 126 ++++++++++++++++++++++++++++++++-------------------- src/RankManager.h | 32 ++++++++++++- 2 files changed, 109 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 9809f1d6c..e64a47eb6 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -5,7 +5,6 @@ #include "Globals.h" #include "RankManager.h" -#include "SQLiteCpp/Transaction.h" #include "inifile/iniFile.h" #include "Protocol/MojangAPI.h" @@ -237,6 +236,8 @@ public: /** Performs the complete migration from INI files to DB. */ bool Migrate(void) { + cRankManager::cMassChangeLock Lock(m_RankManager); + LOGD("Reading groups..."); if (!ReadGroups()) { @@ -615,6 +616,7 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -642,6 +644,7 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -677,6 +680,7 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -712,6 +716,7 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) AStringVector cRankManager::GetRankGroups(const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -742,6 +747,7 @@ AStringVector cRankManager::GetRankGroups(const AString & a_RankName) AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -771,6 +777,7 @@ AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -801,6 +808,7 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) AStringVector cRankManager::GetAllRanks(void) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -825,6 +833,7 @@ AStringVector cRankManager::GetAllRanks(void) AStringVector cRankManager::GetAllGroups(void) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -849,6 +858,7 @@ AStringVector cRankManager::GetAllGroups(void) AStringVector cRankManager::GetAllPermissions(void) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -878,6 +888,7 @@ bool cRankManager::GetPlayerMsgVisuals( ) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try @@ -923,6 +934,7 @@ void cRankManager::AddRank( ) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -965,10 +977,11 @@ void cRankManager::AddRank( void cRankManager::AddGroup(const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Check if such a rank name is already used: + // Check if such a group name is already used: { SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermGroup WHERE Name = ?"); stmt.bind(1, a_GroupName); @@ -982,7 +995,7 @@ void cRankManager::AddGroup(const AString & a_GroupName) } } - // Insert a new rank: + // Insert a new group: SQLite::Statement stmt(m_DB, "INSERT INTO PermGroup (Name) VALUES (?)"); stmt.bind(1, a_GroupName); if (stmt.exec() <= 0) @@ -1001,16 +1014,58 @@ void cRankManager::AddGroup(const AString & a_GroupName) +void cRankManager::AddGroups(const AStringVector & a_GroupNames) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + for (AStringVector::const_iterator itr = a_GroupNames.begin(), end = a_GroupNames.end(); itr != end; ++itr) + { + // Check if such the group name is already used: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermGroup WHERE Name = ?"); + stmt.bind(1, *itr); + if (stmt.executeStep()) + { + if (stmt.getColumn(0).getInt() > 0) + { + // Group already exists, do nothing: + return; + } + } + } + + // Insert a new group: + SQLite::Statement stmt(m_DB, "INSERT INTO PermGroup (Name) VALUES (?)"); + stmt.bind(1, *itr); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add a new group \"%s\".", __FUNCTION__, itr->c_str()); + return; + } + } // for itr - a_GroupNames[] + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add new groups: %s", __FUNCTION__, ex.what()); + } +} + + + + + bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - SQLite::Transaction trans(m_DB); - int GroupID, RankID; - // Get the group's ID: + int GroupID; { SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); stmt.bind(1, a_GroupName); @@ -1023,6 +1078,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a } // Get the rank's ID: + int RankID; { SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); stmt.bind(1, a_RankName); @@ -1066,7 +1122,6 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a } // Adding succeeded: - trans.commit(); return true; } catch (const SQLite::Exception & ex) @@ -1083,12 +1138,10 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrapp the entire operation into a transaction: - SQLite::Transaction trans(m_DB); - // Get the group's ID: int GroupID; { @@ -1134,7 +1187,6 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr } // Adding succeeded: - trans.commit(); return true; } catch (const SQLite::Exception & ex) @@ -1153,12 +1205,10 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrapp the entire operation into a transaction: - SQLite::Transaction trans(m_DB); - // Get the group's ID: int GroupID; { @@ -1207,7 +1257,6 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co } // for itr - a_Permissions[] // Adding succeeded: - trans.commit(); return true; } catch (const SQLite::Exception & ex) @@ -1226,13 +1275,11 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); AStringVector res; try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Get the RankID for the rank being removed: int RemoveRankID; { @@ -1287,8 +1334,6 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl stmt.bind(1, RemoveRankID); stmt.exec(); } - - trans.commit(); } catch (const SQLite::Exception & ex) { @@ -1303,12 +1348,10 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl void cRankManager::RemoveGroup(const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Get the ID of the group: int GroupID; { @@ -1342,8 +1385,6 @@ void cRankManager::RemoveGroup(const AString & a_GroupName) stmt.bind(1, GroupID); stmt.exec(); } - - trans.commit(); } catch (const SQLite::Exception & ex) { @@ -1358,12 +1399,10 @@ void cRankManager::RemoveGroup(const AString & a_GroupName) void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Get the IDs of the group and the rank: int GroupID, RankID; { @@ -1398,8 +1437,6 @@ void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AStrin stmt.bind(1, RankID); stmt.exec(); } - - trans.commit(); } catch (const SQLite::Exception & ex) { @@ -1414,12 +1451,10 @@ void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AStrin void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Get the ID of the group: int GroupID; { @@ -1440,8 +1475,6 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const stmt.bind(2, a_Permission); stmt.exec(); } - - trans.commit(); } catch (const SQLite::Exception & ex) { @@ -1458,12 +1491,10 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Check that NewName doesn't exist: { SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); @@ -1484,7 +1515,6 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa res = (stmt.exec() > 0); } - trans.commit(); return res; } catch (const SQLite::Exception & ex) @@ -1502,12 +1532,10 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap everything into a transaction: - SQLite::Transaction trans(m_DB); - // Check that NewName doesn't exist: { SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); @@ -1528,7 +1556,6 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN res = (stmt.exec() > 0); } - trans.commit(); return res; } catch (const SQLite::Exception & ex) @@ -1546,12 +1573,10 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { - // Wrap the entire operation into a transaction: - SQLite::Transaction trans(m_DB); - // Get the rank ID: int RankID; { @@ -1574,7 +1599,6 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a if (stmt.exec() > 0) { // Successfully updated the player's rank - trans.commit(); return; } } @@ -1587,7 +1611,6 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a if (stmt.exec() > 0) { // Successfully added the player - trans.commit(); return; } @@ -1615,6 +1638,7 @@ void cRankManager::SetRankVisuals( ) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1646,6 +1670,7 @@ bool cRankManager::GetRankVisuals( ) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1675,6 +1700,7 @@ bool cRankManager::GetRankVisuals( bool cRankManager::RankExists(const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1700,6 +1726,7 @@ bool cRankManager::RankExists(const AString & a_RankName) bool cRankManager::GroupExists(const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1725,6 +1752,7 @@ bool cRankManager::GroupExists(const AString & a_GroupName) bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1750,6 +1778,7 @@ bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_RankName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { @@ -1781,6 +1810,7 @@ bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName) { ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); try { diff --git a/src/RankManager.h b/src/RankManager.h index ffe7638e1..3ccbd2fd4 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -9,6 +9,7 @@ #pragma once #include "SQLiteCpp/Database.h" +#include "SQLiteCpp/Transaction.h" @@ -23,6 +24,29 @@ class cMojangAPI; class cRankManager { public: + /** Acquire this lock to perform mass changes. + Improves performance by wrapping everything into a transaction. + Makes sure that no other thread is accessing the DB. */ + class cMassChangeLock + { + public: + cMassChangeLock(cRankManager & a_RankManager) : + m_Lock(a_RankManager.m_CS), + m_Transaction(a_RankManager.m_DB) + { + } + + ~cMassChangeLock() + { + m_Transaction.commit(); + } + + protected: + cCSLock m_Lock; + SQLite::Transaction m_Transaction; + }; + + /** Creates the rank manager. Needs to be initialized before other use. */ cRankManager(void); @@ -80,6 +104,9 @@ public: /** Adds a new permission group. No action if such a group already exists. */ void AddGroup(const AString & a_GroupName); + /** Bulk-adds groups. Group names that already exist are silently skipped. */ + void AddGroups(const AStringVector & a_GroupNames); + /** Adds the specified permission group to the specified rank. Fails if the rank or group names are not found. Returns true if successful, false on error. */ @@ -163,9 +190,12 @@ public: protected: - /** The database storage for all the data. */ + /** The database storage for all the data. Protected by m_CS. */ SQLite::Database m_DB; + /** The mutex protecting m_DB against multi-threaded access. */ + cCriticalSection m_CS; + /** Set to true once the manager is initialized. */ bool m_IsInitialized; -- cgit v1.2.3 From 60ea4bb937ba56c6dcaf57dda377beed972cf0a5 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 11:56:47 +0100 Subject: Removed unused method --- src/WebAdmin.cpp | 22 ---------------------- src/WebAdmin.h | 3 --- 2 files changed, 25 deletions(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index ab6925e55..6882d7bc4 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -159,28 +159,6 @@ void cWebAdmin::Stop(void) -AString cWebAdmin::GetTemplate() -{ - AString retVal = ""; - - char SourceFile[] = "webadmin/template.html"; - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return ""; - } - - // copy the file into the buffer: - f.ReadRestOfFile(retVal); - - return retVal; -} - - - - - void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) { if (!a_Request.HasAuth()) diff --git a/src/WebAdmin.h b/src/WebAdmin.h index f48e8ce9e..aefc1d145 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -208,9 +208,6 @@ protected: /** The HTTP server which provides the underlying HTTP parsing, serialization and events */ cHTTPServer m_HTTPServer; - - AString GetTemplate(void); - /** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */ void HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); -- cgit v1.2.3 From 2321d2af41e935d8353b18592c29d58c766a5658 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 12:01:13 +0100 Subject: Fixed shadowing variable --- src/WebAdmin.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 6882d7bc4..23eedbd14 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -176,9 +176,9 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque } // Check if the contents should be wrapped in the template: - AString URL = a_Request.GetBareURL(); - ASSERT(URL.length() > 0); - bool ShouldWrapInTemplate = ((URL.length() > 1) && (URL[1] != '~')); + AString BareURL = a_Request.GetBareURL(); + ASSERT(BareURL.length() > 0); + bool ShouldWrapInTemplate = ((BareURL.length() > 1) && (BareURL[1] != '~')); // Retrieve the request data: cWebadminRequestData * Data = (cWebadminRequestData *)(a_Request.GetUserData()); @@ -193,7 +193,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque HTTPTemplateRequest TemplateRequest; TemplateRequest.Request.Username = a_Request.GetAuthUsername(); TemplateRequest.Request.Method = a_Request.GetMethod(); - TemplateRequest.Request.Path = URL.substr(1); + TemplateRequest.Request.Path = BareURL.substr(1); if (Data->m_Form.Finish()) { @@ -236,7 +236,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque return; } - AString BaseURL = GetBaseURL(URL); + AString BaseURL = GetBaseURL(BareURL); AString Menu; Template = "{CONTENT}"; AString FoundPlugin; -- cgit v1.2.3 From 8f7b9acb488a2dc4a9c34de499a3cd0e0829ef40 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 12:10:21 +0100 Subject: Fixed forgotten error checking --- src/CraftingRecipes.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 1a31a6e90..085b6e0d5 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -324,7 +324,11 @@ void cCraftingRecipes::LoadRecipes(void) return; } AString Everything; - f.ReadRestOfFile(Everything); + if (!f.ReadRestOfFile(Everything)) + { + LOGWARNING("Cannot read file \"crafting.txt\", no crafting recipes will be available!"); + return; + } f.Close(); // Split it into lines, then process each line as a single recipe: -- cgit v1.2.3 From c3c3d3a72d7517863f015364e62ca0dff46a6807 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 12:14:55 +0100 Subject: Fixed type issues in CraftingRecipe.cpp --- src/CraftingRecipes.cpp | 4 ++-- src/CraftingRecipes.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 085b6e0d5..48178eecb 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -83,7 +83,7 @@ cItem & cCraftingGrid::GetItem(int x, int y) const -void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { // Accessible through scripting, must verify parameters: if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) @@ -228,7 +228,7 @@ void cCraftingRecipe::Clear(void) -void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); } diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 0250d2f68..fe1e15817 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -33,7 +33,7 @@ public: int GetWidth (void) const {return m_Width; } int GetHeight(void) const {return m_Height; } cItem & GetItem (int x, int y) const; - void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth); void SetItem (int x, int y, const cItem & a_Item); void Clear (void); @@ -72,13 +72,13 @@ public: int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); } cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); } const cItem & GetResult (void) const {return m_Result; } - void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetResult (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth); void SetResult (const cItem & a_Item) { m_Result = a_Item; } - void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) + void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); } -- cgit v1.2.3 From 08c55ef98348b13f4375fe683337fbf3cc9a9122 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 13 Aug 2014 13:27:56 +0200 Subject: Logger: Fixed missing timestamp in log messages. --- src/Logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Logger.cpp b/src/Logger.cpp index 572a0e160..cb528e8ab 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -54,7 +54,7 @@ void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) cCSLock Lock(m_CriticalSection); for (size_t i = 0; i < m_LogListeners.size(); i++) { - m_LogListeners[i]->Log(a_Message, a_LogLevel); + m_LogListeners[i]->Log(Line, a_LogLevel); } } -- cgit v1.2.3 From 5921f78e523b3998e72f9c681b8211fd2bc99127 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 13 Aug 2014 13:28:45 +0200 Subject: Logger: Fixed windows debug ODS logger, fixed-size file prefixes. --- src/LoggerListeners.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index 912342a65..b86ab4127 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -17,6 +17,7 @@ class cColouredConsoleListener : public cLogger::cListener { + protected: virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) = 0; virtual void SetDefaultLogColour() = 0; @@ -24,7 +25,7 @@ virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override { SetLogColour(a_LogLevel); - puts(a_Message.c_str()); + fputs(a_Message.c_str(), stdout); SetDefaultLogColour(); } }; @@ -46,7 +47,7 @@ { } - #ifdef DEBUG + #ifdef _DEBUG virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override { super::Log(a_Message, a_LogLevel); @@ -289,31 +290,31 @@ cFileListener::cFileListener(void) void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) { - AString LogLevelString; + const char * LogLevelPrefix = "U "; switch (a_LogLevel) { case cLogger::llRegular: { - LogLevelString = "Log"; + LogLevelPrefix = " "; break; } case cLogger::llInfo: { - LogLevelString = "Info"; + LogLevelPrefix = "i "; break; } case cLogger::llWarning: { - LogLevelString = "Warning"; + LogLevelPrefix = "W "; break; } case cLogger::llError: { - LogLevelString = "Error"; + LogLevelPrefix = "E "; break; } } - m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + m_File.Printf("%s: %s", LogLevelPrefix, a_Message.c_str()); } -- cgit v1.2.3 From 36e918ce9bd546efa25987027a73e0f1d8fa192d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 13 Aug 2014 13:31:19 +0200 Subject: File logger prefixes are 4 chars wide. --- src/LoggerListeners.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index b86ab4127..836536cbd 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -290,31 +290,31 @@ cFileListener::cFileListener(void) void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) { - const char * LogLevelPrefix = "U "; + const char * LogLevelPrefix = "Unkn "; switch (a_LogLevel) { case cLogger::llRegular: { - LogLevelPrefix = " "; + LogLevelPrefix = " "; break; } case cLogger::llInfo: { - LogLevelPrefix = "i "; + LogLevelPrefix = "info "; break; } case cLogger::llWarning: { - LogLevelPrefix = "W "; + LogLevelPrefix = "Warn "; break; } case cLogger::llError: { - LogLevelPrefix = "E "; + LogLevelPrefix = "Err "; break; } } - m_File.Printf("%s: %s", LogLevelPrefix, a_Message.c_str()); + m_File.Printf("%s%s", LogLevelPrefix, a_Message.c_str()); } -- cgit v1.2.3 From 781e1e6264794ec0fddccd37a76f7a78a3fa8b09 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:03:56 +0100 Subject: Fixed Integer pasing warnings in CraftingRecipies.cpp --- src/CraftingRecipes.cpp | 6 ++--- src/StringUtils.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 48178eecb..2d80ecaf8 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -392,8 +392,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine } if (ResultSplit.size() > 1) { - Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); - if (Recipe->m_Result.m_ItemCount == 0) + if (!StringToInteger(ResultSplit[1].c_str(), Recipe->m_Result.m_ItemCount)) { LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); LOGINFO("Offending line: \"%s\"", a_RecipeLine.c_str()); @@ -445,8 +444,7 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) if (Split.size() > 1) { AString Damage = TrimString(Split[1]); - a_Item.m_ItemDamage = atoi(Damage.c_str()); - if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0)) + if (!StringToInteger(Damage.c_str(), a_Item.m_ItemDamage)) { // Parsing the number failed return false; diff --git a/src/StringUtils.h b/src/StringUtils.h index 142aaf59b..56ac83942 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -99,6 +99,68 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); +/// Parses any integer type. Checks bounds and +template +bool StringToInteger(AString a_str, T& a_Num) +{ + size_t i = 0; + T positive = true; + T result = 0; + if (a_str[0] == '+') + { + i++; + } + else if (a_str[0] == '-') + { + i++; + positive = false; + } + if (positive) + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits::max() / 10 < result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits::max() - digit < result) + { + return false; + } + result += digit; + } + } + else + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits::min() / 10 > result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits::min() + digit > result) + { + return false; + } + result -= digit; + } + } + a_Num = result; + return true; +} + // If you have any other string helper functions, declare them here -- cgit v1.2.3 From fecd607d7496d77a488757871a5abe60f789572b Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:15:29 +0100 Subject: Added missing header --- src/StringUtils.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index 56ac83942..30a193845 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -9,6 +9,7 @@ #pragma once #include +#include -- cgit v1.2.3 From f4d268636a02346acc46c993666fe02bbc1ff0b8 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:37:07 +0100 Subject: Fixed comments --- src/StringUtils.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index 30a193845..a78f8b0bf 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -100,12 +100,12 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); -/// Parses any integer type. Checks bounds and +/// Parses any integer type. Checks bounds and returns errors out of band. template -bool StringToInteger(AString a_str, T& a_Num) +bool StringToInteger(const AString& a_str, T& a_Num) { size_t i = 0; - T positive = true; + bool positive = true; T result = 0; if (a_str[0] == '+') { @@ -118,7 +118,7 @@ bool StringToInteger(AString a_str, T& a_Num) } if (positive) { - for(; i <= a_str.size(); i++) + for(size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { @@ -139,7 +139,7 @@ bool StringToInteger(AString a_str, T& a_Num) } else { - for(; i <= a_str.size(); i++) + for(size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { -- cgit v1.2.3 From a544c0238ba4c94d78692a7592107f8e510893ee Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 18:53:23 +0200 Subject: Implement ability to push minecarts on curved rails --- src/Entities/Minecart.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index d4eadc5d5..19eaa207f 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -871,11 +871,79 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) return true; } case E_META_RAIL_CURVED_ZM_XM: + case E_META_RAIL_CURVED_ZP_XP: + { + Vector3d Distance( + MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), + 0, + MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() + ); + + if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + { + if ( (-GetSpeedX() * 0.4) < 0.01 ) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( 4/sqrt(2) ); + } + else + { + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( GetSpeedZ() * 0.4 ); + } + } + else + { + if ((GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } + else + { + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); + } + } + break; + } case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: - case E_META_RAIL_CURVED_ZP_XP: { - // TODO - simply can't be bothered right now + Vector3d Distance( + MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), + 0, + MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() + ); + + if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) + { + if ( (GetSpeedX() * 0.4) < 0.01 ) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( 4/sqrt(2) ); + } + else + { + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( GetSpeedZ() * 0.4 ); + } + } + else + { + if ((-GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } + else + { + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); + } + } break; } default: break; -- cgit v1.2.3 From 3698c5c8295e6a6a0f37b17f3c04bb118cc58bf6 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:16:00 +0200 Subject: Fixed braces and intendation errors --- src/Entities/Minecart.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 19eaa207f..5cf56d3d2 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -879,8 +879,12 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) Distance.z = 0.0001; - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + if ( Distance.z == 0. ) + { + Distance.z = 0.0001; + } + + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) { if ( (-GetSpeedX() * 0.4) < 0.01 ) { @@ -917,7 +921,11 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( Distance.z == 0. ) + { + Distance.z = 0.0001; + } + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) { if ( (GetSpeedX() * 0.4) < 0.01 ) -- cgit v1.2.3 From 3f117897fbda4eec95ad5cdd728f197840dd7224 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:18:11 +0200 Subject: Another intendation error --- src/Entities/Minecart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 5cf56d3d2..cd5e2adaa 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -881,9 +881,9 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) if ( Distance.z == 0. ) { - Distance.z = 0.0001; + Distance.z = 0.0001; } - + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) { if ( (-GetSpeedX() * 0.4) < 0.01 ) -- cgit v1.2.3 From 2d2d4ff33b74eefe053cce4d9a5daada65ed496b Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:47:43 +0200 Subject: Further fixing of coding style errors --- src/Entities/Minecart.cpp | 48 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index cd5e2adaa..45b9782f3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -879,14 +879,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) + if (Distance.z == 0.) { Distance.z = 0.0001; } - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + if (((Distance.z >= 0) && ((Distance.x / Distance.z) >= 1)) || + ((Distance.z<0) && ((Distance.x / Distance.z) <= 1))) { - if ( (-GetSpeedX() * 0.4) < 0.01 ) + if ((-GetSpeedX() * 0.4) < 0.01) { AddSpeedX( -4/sqrt(2) ); AddSpeedZ( 4/sqrt(2) ); @@ -897,18 +898,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ( GetSpeedZ() * 0.4 ); } } + else if ((GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } else { - if ((GetSpeedX() * 0.4) < 0.01) - { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); - } - else - { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); - } + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); } break; } @@ -921,14 +919,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) + if (Distance.z == 0.) { Distance.z = 0.0001; } - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) + if (((Distance.z >= 0) && ((Distance.x / Distance.z) <= -1)) || + ((Distance.z<0) && ((Distance.x / Distance.z) >= -1))) { - if ( (GetSpeedX() * 0.4) < 0.01 ) + if ((GetSpeedX() * 0.4) < 0.01) { AddSpeedX( 4/sqrt(2) ); AddSpeedZ( 4/sqrt(2) ); @@ -939,18 +938,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ( GetSpeedZ() * 0.4 ); } } + else if ((-GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } else { - if ((-GetSpeedX() * 0.4) < 0.01) - { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); - } - else - { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); - } + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); } break; } -- cgit v1.2.3 From 008c1cdaf436dec2d7a4a925c6a600570594d6a2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 14 Aug 2014 01:03:30 +0200 Subject: CheckBasicStyle checks the src folder as well. --- src/CMakeLists.txt | 2 +- src/Chunk.cpp | 26 ++++++++++++++++---------- src/Chunk.h | 2 +- src/World.cpp | 2 +- src/World.h | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db9c61082..3994399f2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -234,7 +234,7 @@ endif() # Generate a list of all source files: -set(ALLFILES "") +set(ALLFILES "${SRCS}" "${HDRS}") foreach(folder ${FOLDERS}) get_directory_property(FOLDER_SRCS DIRECTORY ${folder} DEFINITION SRCS) foreach (src ${FOLDER_SRCS}) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a79a485a6..7bdf4196d 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -579,7 +579,7 @@ void cChunk::Tick(float a_Dt) } for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) - { + { if (!((*itr)->IsMob())) // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players) { // Tick all entities in this chunk (except mobs): @@ -594,17 +594,19 @@ void cChunk::Tick(float a_Dt) itr = m_Entities.erase(itr); delete ToDelete; } - else if ((*itr)->IsWorldTravellingFrom(m_World)) // Remove all entities that are travelling to another world: + else if ((*itr)->IsWorldTravellingFrom(m_World)) { + // Remove all entities that are travelling to another world MarkDirty(); (*itr)->SetWorldTravellingFrom(NULL); itr = m_Entities.erase(itr); } - else if ( // If any entity moved out of the chunk, move it to the neighbor: + else if ( ((*itr)->GetChunkX() != m_PosX) || ((*itr)->GetChunkZ() != m_PosZ) ) { + // The entity moved out of the chunk, move it to the neighbor MarkDirty(); MoveEntityToNewChunk(*itr); itr = m_Entities.erase(itr); @@ -885,14 +887,14 @@ void cChunk::ApplyWeatherToTop() SetBlock(X, Height, Z, E_BLOCK_ICE, 0); } else if ( - (m_World->IsDeepSnowEnabled()) && - ( - (TopBlock == E_BLOCK_RED_ROSE) || - (TopBlock == E_BLOCK_YELLOW_FLOWER) || - (TopBlock == E_BLOCK_RED_MUSHROOM) || - (TopBlock == E_BLOCK_BROWN_MUSHROOM) - ) + (m_World->IsDeepSnowEnabled()) && + ( + (TopBlock == E_BLOCK_RED_ROSE) || + (TopBlock == E_BLOCK_YELLOW_FLOWER) || + (TopBlock == E_BLOCK_RED_MUSHROOM) || + (TopBlock == E_BLOCK_BROWN_MUSHROOM) ) + ) { SetBlock(X, Height, Z, E_BLOCK_SNOW, 0); } @@ -2142,10 +2144,14 @@ bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_Blo case E_BLOCK_DROPPER: case E_BLOCK_DISPENSER: case E_BLOCK_NOTE_BLOCK: + { break; + } default: + { // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out return false; + } } if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) diff --git a/src/Chunk.h b/src/Chunk.h index 813a8b13f..72a1f6c95 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -241,7 +241,7 @@ public: bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible /** Calls the callback for the redstone powered entity at the specified coords; returns false if there's no redstone powered entity at those coords, true if found */ - bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); + bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible diff --git a/src/World.cpp b/src/World.cpp index 5298f3b03..b357b8a23 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3327,7 +3327,7 @@ void cWorld::AddQueuedPlayers(void) cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr) { - ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW? + ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW? LOGD("Adding player %s to world \"%s\".", (*itr)->GetName().c_str(), m_WorldName.c_str()); m_Players.push_back(*itr); diff --git a/src/World.h b/src/World.h index 6df1758e9..578c9682b 100644 --- a/src/World.h +++ b/src/World.h @@ -235,7 +235,7 @@ public: void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); -- cgit v1.2.3 From e3a74f379fc103f40e6bf85e626d7bac7db236af Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Thu, 14 Aug 2014 14:29:46 +0200 Subject: Further changes in coding style --- src/Entities/Minecart.cpp | 66 ++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 45b9782f3..8e11d8a07 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -873,80 +873,70 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) case E_META_RAIL_CURVED_ZM_XM: case E_META_RAIL_CURVED_ZP_XP: { - Vector3d Distance( - MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), - 0, - MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() - ); + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); - if (Distance.z == 0.) - { - Distance.z = 0.0001; - } + Distance.z = std::max(Distance.z, 0.001); - if (((Distance.z >= 0) && ((Distance.x / Distance.z) >= 1)) || - ((Distance.z<0) && ((Distance.x / Distance.z) <= 1))) + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) + ) { if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( 4/sqrt(2) ); + AddSpeedX(-4/sqrt(2)); + AddSpeedZ(4/sqrt(2)); } else { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( GetSpeedZ() * 0.4 ); + SetSpeedX(-GetSpeedX() * 0.4); + SetSpeedZ(GetSpeedZ() * 0.4); } } else if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); + AddSpeedX(4/sqrt(2)); + AddSpeedZ(-4/sqrt(2)); } else { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); + SetSpeedX(GetSpeedX() * 0.4); + SetSpeedZ(-GetSpeedZ() * 0.4); } break; } case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: { - Vector3d Distance( - MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), - 0, - MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() - ); + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); - if (Distance.z == 0.) - { - Distance.z = 0.0001; - } + Distance.z = std::max(Distance.z, 0.001); - if (((Distance.z >= 0) && ((Distance.x / Distance.z) <= -1)) || - ((Distance.z<0) && ((Distance.x / Distance.z) >= -1))) + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) + ) { if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( 4/sqrt(2) ); + AddSpeedX(4/sqrt(2)); + AddSpeedZ(4/sqrt(2)); } else { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( GetSpeedZ() * 0.4 ); + SetSpeedX(GetSpeedX() * 0.4); + SetSpeedZ(GetSpeedZ() * 0.4); } } else if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); + AddSpeedX(-4/sqrt(2)); + AddSpeedZ(-4/sqrt(2)); } else { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); + SetSpeedX(-GetSpeedX() * 0.4); + SetSpeedZ(-GetSpeedZ() * 0.4); } break; } -- cgit v1.2.3 From 3a7089539cc6be6e4ed00e17497e0dd327b9d67b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 14 Aug 2014 23:06:46 +0200 Subject: RankMgr: Removed unneeded testing code. --- src/RankManager.cpp | 210 +--------------------------------------------------- 1 file changed, 2 insertions(+), 208 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index e64a47eb6..96c4baa56 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -12,215 +12,9 @@ -/* -// This code is for internal testing while developing the cRankManager class -static class cRankMgrTest -{ -public: - cRankMgrTest(void) : - m_Mgr() - { - // Initialize logging: - new cMCLogger(); - AString UUID = "b1caf24202a841a78055a079c460eee7"; // UUID for "xoft" - LOG("Testing UUID %s", UUID.c_str()); - - // Test the initial state of the ranks: - LOG("Initial test:"); - ReportPlayer(UUID); - - // Add a rank, a few groups and permissions and set the player to use them: - LOG("Adding data..."); - m_Mgr.AddRank("TestRank1", "[test]", "[/test]", "7"); - m_Mgr.AddRank("TestRank2", "[t2]", "[/t2]", "8"); - m_Mgr.AddGroup("TestGroup1"); - m_Mgr.AddGroup("TestGroup2"); - m_Mgr.AddGroupToRank("TestGroup1", "TestRank1"); - m_Mgr.AddGroupToRank("TestGroup2", "TestRank1"); - m_Mgr.AddGroupToRank("TestGroup2", "TestRank2"); - m_Mgr.AddPermissionToGroup("testpermission1.1", "TestGroup1"); - m_Mgr.AddPermissionToGroup("testpermission1.2", "TestGroup1"); - m_Mgr.AddPermissionToGroup("testpermission1.3", "TestGroup1"); - m_Mgr.AddPermissionToGroup("common", "TestGroup1"); - m_Mgr.AddPermissionToGroup("testpermission2.1", "TestGroup2"); - m_Mgr.AddPermissionToGroup("common", "TestGroup2"); - m_Mgr.SetPlayerRank(UUID, "xoft", "TestRank1"); - - // Test the added data: - LOG("Testing the added data:"); - LOG("IsGroupInRank(TestGroup1, TestRank1) = %s", m_Mgr.IsGroupInRank("TestGroup1", "TestRank1") ? "true" : "false"); - LOG("IsGroupInRank(TestGroup3, TestRank1) = %s", m_Mgr.IsGroupInRank("TestGroup3", "TestRank1") ? "true" : "false"); - LOG("IsPermissionInGroup(testpermission1.2, TestGroup1) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup1") ? "true" : "false"); // Existing permission, in group - LOG("IsPermissionInGroup(testpermission1.2, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.2", "TestGroup2") ? "true" : "false"); // Existing permission, not in group - LOG("IsPermissionInGroup(testpermission1.9, TestGroup2) = %s", m_Mgr.IsPermissionInGroup("testpermission1.9", "TestGroup2") ? "true" : "false"); // Non-existing permission - LOG("IsPlayerRankSet(%s) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID) ? "true" : "false"); - LOG("IsPlayerRankSet(%s1) = %s", UUID.c_str(), m_Mgr.IsPlayerRankSet(UUID + "1") ? "true" : "false"); - LOG("GroupExists(TestGroup1) = %s", m_Mgr.GroupExists("TestGroup1") ? "true" : "false"); - LOG("GroupExists(TestGroup3) = %s", m_Mgr.GroupExists("TestGroup3") ? "true" : "false"); - LOG("RankExists(TestRank1) = %s", m_Mgr.RankExists("TestRank1") ? "true" : "false"); - LOG("RankExists(NonexistentRank) = %s", m_Mgr.RankExists("NonexistentRank") ? "true" : "false"); - ReportRankGroups("TestRank1"); - ReportRankGroups("NonexistentRank"); - ReportGroupPermissions("TestGroup1"); - ReportGroupPermissions("NonexistentGroup"); - - // Report the contents of the DB: - ReportAll(); - - // Test the assignments above: - LOG("After-assignment test:"); - ReportPlayer(UUID); - - // Test removing a permission from a group: - LOG("Removing permission testpermission1.3 from group TestGroup1."); - m_Mgr.RemovePermissionFromGroup("testpermission1.3", "TestGroup1"); - ReportGroupPermissions("TestGroup1"); - LOG("Removing permission common from group TestGroup1."); - m_Mgr.RemovePermissionFromGroup("common", "TestGroup1"); - ReportGroupPermissions("TestGroup1"); // Check that it's not present - ReportGroupPermissions("TestGroup2"); // Check that it's still present here - - // Test removing a group from rank: - LOG("Removing group TestGroup2 from rank TestRank1."); - m_Mgr.RemoveGroupFromRank("TestGroup2", "TestRank1"); - ReportRankGroups("TestRank1"); - LOG("Removing group TestGroup3 from rank TestRank1."); - m_Mgr.RemoveGroupFromRank("TestGroup3", "TestRank1"); - ReportRankGroups("TestRank1"); - - // Test re-adding the groups: - LOG("Re-adding groups to TestRank1."); - m_Mgr.AddGroupToRank("TestGroup1", "TestRank1"); - m_Mgr.AddGroupToRank("TestGroup2", "TestRank1"); - ReportRankGroups("TestRank1"); - - // Test removing a group altogether: - LOG("Removing group TestGroup2"); - m_Mgr.RemoveGroup("TestGroup2"); - ReportAll(); - - // Test removing a rank: - LOG("Removing rank TestRank2, replacing with rank TestRank1."); - m_Mgr.RemoveRank("TestRank2", "TestRank1"); - ReportAll(); - LOG("Removing rank Test altogether."); - m_Mgr.RemoveRank("Test", ""); - ReportAll(); - - // Test renaming a rank: - LOG("Renaming rank TestRank1 to Test"); - m_Mgr.RenameRank("TestRank1", "Test"); - ReportRankGroups("TestRank1"); - ReportRankGroups("Test"); - LOG("Player after renaming:"); - ReportPlayer(UUID); - - // Test renaming a group: - LOG("Renaming group TestGroup1 to Test"); - m_Mgr.RenameGroup("TestGroup1", "Test"); - ReportGroupPermissions("TestGroup1"); - ReportGroupPermissions("Test"); - LOG("Player after renaming:"); - ReportPlayer(UUID); - m_Mgr.RenameGroup("Test", "TestGroup1"); - - // Test removing the rank in favor of another one: - m_Mgr.RemoveRank("Test", "TestRank2"); - LOG("After-removal test:"); - ReportPlayer(UUID); - - LOG("Done."); - } - - - void ReportAll(void) - { - // Report all ranks: - AStringVector Ranks = m_Mgr.GetAllRanks(); - LOG("All ranks (%u):", (unsigned)Ranks.size()); - for (AStringVector::const_iterator itr = Ranks.begin(), end = Ranks.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - - // Report all groups: - AStringVector Groups = m_Mgr.GetAllGroups(); - LOG("All groups (%u):", (unsigned)Groups.size()); - for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - - // Report all permissions: - AStringVector Permissions = m_Mgr.GetAllPermissions(); - LOG("All permissions (%u):", (unsigned)Permissions.size()); - for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - } - - - void ReportPlayer(const AString & a_PlayerUUID) - { - // Get the player's UUID and rank: - LOG(" Rank: '%s'", m_Mgr.GetPlayerRankName(a_PlayerUUID).c_str()); - - // List all the permission groups for the player: - AStringVector Groups = m_Mgr.GetPlayerGroups(a_PlayerUUID); - LOG(" Groups (%u):", (unsigned)Groups.size()); - for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) - { - LOG(" '%s'" , itr->c_str()); - } // for itr - Groups[] - - // List all the permissions for the player: - AStringVector Permissions = m_Mgr.GetPlayerPermissions(a_PlayerUUID); - LOG(" Permissions (%u):", (unsigned)Permissions.size()); - for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } // for itr - Groups[] - } - - - void ReportRankGroups(const AString & a_RankName) - { - AStringVector Groups = m_Mgr.GetRankGroups(a_RankName); - LOG("Groups in rank %s: %u", a_RankName.c_str(), (unsigned)Groups.size()); - for (AStringVector::const_iterator itr = Groups.begin(), end = Groups.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - AStringVector Permissions = m_Mgr.GetRankPermissions(a_RankName); - LOG("Permissions in rank %s: %u", a_RankName.c_str(), (unsigned)Permissions.size()); - for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - } - - - void ReportGroupPermissions(const AString & a_GroupName) - { - AStringVector Permissions = m_Mgr.GetGroupPermissions(a_GroupName); - LOG("Permissions in group %s: %u", a_GroupName.c_str(), (unsigned)Permissions.size()); - for (AStringVector::const_iterator itr = Permissions.begin(), end = Permissions.end(); itr != end; ++itr) - { - LOG(" '%s'", itr->c_str()); - } - } - -protected: - cRankManager m_Mgr; -} g_RankMgrTest; -//*/ - - - - - //////////////////////////////////////////////////////////////////////////////// +// cRankManagerIniMigrator: + /** Migrates from groups.ini and users.ini into the rankmanager DB */ class cRankManagerIniMigrator { -- cgit v1.2.3 From 1f4a1383c2b261aa4644f8efeb31eedce4a62bf4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 15 Aug 2014 07:19:13 +0200 Subject: Removed an unneeded cast. --- src/OSSupport/File.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index af8a832f6..2194c46ee 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -259,7 +259,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) size_t DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign((size_t)DataSize, '\0'); + a_Contents.assign(DataSize, '\0'); return Read((void *)a_Contents.data(), DataSize); } -- cgit v1.2.3 From 0f631febfc3f670e8e9eb60ec4f89659ad7d0c71 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 13:40:56 +0200 Subject: Add some comments --- src/Entities/Minecart.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 8e11d8a07..0455c9ab3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -875,17 +875,23 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + // Prevent division by small numbers Distance.z = std::max(Distance.z, 0.001); + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line z = -x, the perpendicular line to this is z = x. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. + */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) { - if ((-GetSpeedX() * 0.4) < 0.01) + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - AddSpeedX(-4/sqrt(2)); - AddSpeedZ(4/sqrt(2)); + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); } else { @@ -893,10 +899,10 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ(GetSpeedZ() * 0.4); } } - else if ((GetSpeedX() * 0.4) < 0.01) + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - AddSpeedX(4/sqrt(2)); - AddSpeedZ(-4/sqrt(2)); + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); } else { @@ -910,8 +916,13 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + // Prevent division by small numbers Distance.z = std::max(Distance.z, 0.001); + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line z = x, the perpendicular line to this is z = -x. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) @@ -919,8 +930,8 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX(4/sqrt(2)); - AddSpeedZ(4/sqrt(2)); + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); } else { @@ -930,8 +941,8 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } else if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX(-4/sqrt(2)); - AddSpeedZ(-4/sqrt(2)); + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); } else { -- cgit v1.2.3 From be03b84048a49e04db11aa6ce80b3d18fff313b1 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 13:43:45 +0200 Subject: End of comment moved away from new line --- src/Entities/Minecart.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 0455c9ab3..f190d972e 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -881,8 +881,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line z = -x, the perpendicular line to this is z = x. - In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. - */ + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) -- cgit v1.2.3 From c473d8cfb82009411f5a3977b7041ee49ba08003 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 14:00:51 +0200 Subject: Clarify comment message --- src/Entities/Minecart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f190d972e..4753f720d 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -880,7 +880,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). - The minecart moves along the line z = -x, the perpendicular line to this is z = x. + The minecart moves along the line x = -z, the perpendicular line to this is x = z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || @@ -920,7 +920,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). - The minecart moves along the line z = x, the perpendicular line to this is z = -x. + The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || -- cgit v1.2.3 From 72c02ceb171949acd07338e77c8ee0d3439f8173 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 17:54:43 +0200 Subject: Added a lot of comments --- src/Entities/Minecart.cpp | 66 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 4753f720d..9420eca02 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -876,7 +876,10 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - Distance.z = std::max(Distance.z, 0.001); + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). @@ -886,27 +889,27 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - { - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - { + { // Moving -X + Z + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ speedX >= 0 + { // Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else - { - SetSpeedX(-GetSpeedX() * 0.4); - SetSpeedZ(GetSpeedZ() * 0.4); + else // ~ SpeedX < 0 + { // Moving in the "right" direction. Only accelerate it a bit. + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - { + } // Moving +X -Z + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ SpeedX <= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else - { - SetSpeedX(GetSpeedX() * 0.4); - SetSpeedZ(-GetSpeedZ() * 0.4); + else // ~ SpeedX > 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } break; } @@ -916,37 +919,40 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - Distance.z = std::max(Distance.z, 0.001); + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ - if ( + if ( // Moving +X +Z ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) { - if ((GetSpeedX() * 0.4) < 0.01) - { + if ((GetSpeedX() * 0.4) < 0.01) // ~ SpeedX <= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else - { - SetSpeedX(GetSpeedX() * 0.4); - SetSpeedZ(GetSpeedZ() * 0.4); + else // SpeedX > 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } - else if ((-GetSpeedX() * 0.4) < 0.01) - { + } // Moving -X -Z + else if ((-GetSpeedX() * 0.4) < 0.01) // ~ SpeedX >= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else - { - SetSpeedX(-GetSpeedX() * 0.4); - SetSpeedZ(-GetSpeedZ() * 0.4); + else // ~ SpeedX < 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } break; } -- cgit v1.2.3 From 9395cf0bca15371b8dfdb7a444c1e9f7cca0252c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 16 Aug 2014 18:02:16 +0200 Subject: First implementation of HOOK_SERVER_PING. --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 19 +++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ 5 files changed, 43 insertions(+) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 39d53674b..6f05af51b 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -91,6 +91,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; + virtual bool OnServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 0f3f25d75..066e050d6 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1193,6 +1193,26 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity +bool cPluginLua::OnServerPing(const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), a_Username, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 2cea644c1..2d98477f0 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -117,6 +117,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; + virtual bool OnServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 89bfe3566..b9d28205d 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1189,6 +1189,25 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil +bool cPluginManager::CallHookServerPing(const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +{ + FIND_HOOK(HOOK_SERVER_PING); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnServerPing(a_Username, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { FIND_HOOK(HOOK_SPAWNED_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 44a94e316..104e4c7a9 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -120,6 +120,7 @@ public: HOOK_PRE_CRAFTING, HOOK_PROJECTILE_HIT_BLOCK, HOOK_PROJECTILE_HIT_ENTITY, + HOOK_SERVER_PING, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, HOOK_SPAWNING_ENTITY, @@ -225,6 +226,7 @@ public: bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); + bool CallHookServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); -- cgit v1.2.3 From a68c70c900d0f3b3842d78af49423890f29af180 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 16 Aug 2014 18:44:14 +0200 Subject: Better OnPlayerMoving hook. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Entities/Player.cpp | 12 ++++++++++-- 6 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 39d53674b..2cc5cade3 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -73,7 +73,7 @@ public: virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; - virtual bool OnPlayerMoved (cPlayer & a_Player) = 0; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) = 0; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 0f3f25d75..37db78994 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -835,14 +835,14 @@ bool cPluginLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_Block -bool cPluginLua::OnPlayerMoved(cPlayer & a_Player) +bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Player, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_OldPosition, &a_NewPosition, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 2cea644c1..6df86f7a1 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -98,7 +98,7 @@ public: virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override; - virtual bool OnPlayerMoved (cPlayer & a_Player) override; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 89bfe3566..dbc359f0e 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -849,14 +849,14 @@ bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, i -bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player) +bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) { FIND_HOOK(HOOK_PLAYER_MOVING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnPlayerMoved(a_Player)) + if ((*itr)->OnPlayerMoving(a_Player, a_OldPosition, a_NewPosition)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 44a94e316..e0573f386 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -206,7 +206,7 @@ public: bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward); bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel); bool CallHookPlayerJoined (cPlayer & a_Player); - bool CallHookPlayerMoving (cPlayer & a_Player); + bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); bool CallHookPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 4398a5bf3..ab4ff3161 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -225,16 +225,24 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) SendExperience(); } + bool CanMove = true; if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick? { // Apply food exhaustion from movement: ApplyFoodExhaustionFromMovement(); - cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this); + if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this, m_LastPos, GetPosition())) + { + CanMove = false; + TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z); + } m_ClientHandle->StreamChunks(); } - BroadcastMovementUpdate(m_ClientHandle); + if (CanMove) + { + BroadcastMovementUpdate(m_ClientHandle); + } if (m_Health > 0) // make sure player is alive { -- cgit v1.2.3 From 9522bd842ea845cc37b4d2a60333453c12b024a4 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 18 Aug 2014 12:53:36 +0200 Subject: SwamplandM: Fixed sometimes having no mountains. --- src/Generating/HeiGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index ba11b31b4..c3f3b38a9 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -432,7 +432,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131 /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132 /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133 - /* biSwamplandM */ { 1.0f, 2.0f, 1.10f, 5.0f, 0.01f, 8.0f, 60}, // 134 + /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134 // Biomes 135 .. 139 unused, 5 empty placeholders here: {}, {}, {}, {}, {}, // 135 .. 139 -- cgit v1.2.3 From 80559406f99bd32de066c8a80b9f920b8b57b8f1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 17 Aug 2014 22:47:00 +0200 Subject: Player saving creates the "players" folder, if needed. Fixes #1268. --- src/Entities/Player.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ab4ff3161..0b13e62a9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1842,6 +1842,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) bool cPlayer::SaveToDisk() { + cFile::CreateFolder(FILE_IO_PREFIX + AString("players/")); // Create the "players" folder, if it doesn't exist yet (#1268) cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2)); // create the JSON data -- cgit v1.2.3 From c70886a7124e5940b67cb4f1b4593f103f2707d8 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Mon, 18 Aug 2014 01:57:44 +0200 Subject: Adjust comment formatting --- src/Entities/Minecart.cpp | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 9420eca02..13469edb3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -889,25 +889,35 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - { // Moving -X + Z - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ speedX >= 0 - { // Immobile or not moving in the "right" direction. Give it a bump! + // Moving -X +Z + { + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + // ~ speedX >= 0 + { + // Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else // ~ SpeedX < 0 - { // Moving in the "right" direction. Only accelerate it a bit. + else + // ~ SpeedX < 0 + { + // Moving in the "right" direction. Only accelerate it a bit. SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } // Moving +X -Z - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ SpeedX <= 0 - { // Immobile or not moving in the "right" direction + } + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + // Moving +X -Z + // ~ SpeedX <= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else // ~ SpeedX > 0 - { // Moving in the "right" direction + else + // ~ SpeedX > 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } @@ -928,29 +938,39 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ - if ( // Moving +X +Z + if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) + // Moving +X +Z { - if ((GetSpeedX() * 0.4) < 0.01) // ~ SpeedX <= 0 - { // Immobile or not moving in the "right" direction + if ((GetSpeedX() * 0.4) < 0.01) + // ~ SpeedX <= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else // SpeedX > 0 - { // Moving in the "right" direction + else + // SpeedX > 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } // Moving -X -Z - else if ((-GetSpeedX() * 0.4) < 0.01) // ~ SpeedX >= 0 - { // Immobile or not moving in the "right" direction + } + else if ((-GetSpeedX() * 0.4) < 0.01) + // Moving -X -Z + // ~ SpeedX >= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else // ~ SpeedX < 0 - { // Moving in the "right" direction + else + // ~ SpeedX < 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } -- cgit v1.2.3 From e4fc05574bc4d888a8794d68c518e5242c494f69 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 18 Aug 2014 22:48:15 +0200 Subject: Player: Silenced a few type conversion warnings. --- src/Entities/Player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0b13e62a9..32290885d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -892,7 +892,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) Pickups.Add(cItem(E_ITEM_RED_APPLE)); } - m_Stats.AddValue(statItemsDropped, Pickups.Size()); + m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size()); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! @@ -1618,7 +1618,7 @@ void cPlayer::TossPickup(const cItem & a_Item) void cPlayer::TossItems(const cItems & a_Items) { - m_Stats.AddValue(statItemsDropped, a_Items.Size()); + m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size()); double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); -- cgit v1.2.3 From d3fd63c9eb5f783da0186efcef81a5b0eb9338d6 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 12:38:15 +0200 Subject: Added some Enchantments - Bow enchantments: Infinity, Flame and Power - Sword and tools enchantments: Fire Aspect, Bane of Arthropods, Smite, Sharpness --- src/Entities/ArrowEntity.cpp | 26 ++++++++++++++++--- src/Entities/ArrowEntity.h | 7 +++-- src/Entities/Entity.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++- src/Items/ItemBow.h | 12 ++++++++- 4 files changed, 100 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 913519c4c..c4fd378fb 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -18,6 +18,7 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), + m_Creator(a_Creator), m_HitBlockPos(Vector3i(0, 0, 0)) { SetSpeed(a_Speed); @@ -43,6 +44,7 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), + m_Creator(&a_Player), m_HitBlockPos(0, 0, 0) { if (a_Player.IsGameModeCreative()) @@ -68,9 +70,6 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const } - - - void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001)) @@ -90,6 +89,13 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (m_TicksLeftBurning > 0)) + { + m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); + m_World->SpawnPrimedTNT(X, Y, Z); + } + } @@ -103,8 +109,22 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } + LOGD("Arrow hit an entity"); + + int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); + if (PowerLevel > 0) + { + LOGD("Arrow hit an entity 2"); + int ExtraDamage = 0.25 * (PowerLevel + 1); + Damage += ceil(ExtraDamage); + } a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); + if (m_TicksLeftBurning > 0) + { + a_EntityHit.StartBurning(100); + } + // Broadcast successful hit sound GetWorld()->BroadcastSoundEffect("random.successful_hit", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 4bfcb1f6d..2ea6e9fde 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -10,6 +10,7 @@ + // tolua_begin class cArrowEntity : @@ -46,7 +47,7 @@ public: /// Returns the damage modifier coeff. double GetDamageCoeff(void) const { return m_DamageCoeff; } - + /// Sets the damage modifier coeff void SetDamageCoeff(double a_DamageCoeff) { m_DamageCoeff = a_DamageCoeff; } @@ -89,7 +90,9 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; - + + cEntity * m_Creator; + /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air Vector3i m_HitBlockPos; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 32f220897..398f7703b 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,8 +316,68 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - if (!Player->IsOnGround()) + + cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; + + int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); + int SmiteLevel = Enchantments.GetLevel(cEnchantments::enchSmite); + int BaneOfArthropodsLevel = Enchantments.GetLevel(cEnchantments::enchBaneOfArthropods); + + if (SharpnessLevel > 0) + { + a_TDI.RawDamage += 1.25 * SharpnessLevel; + } + else if (SmiteLevel > 0) + { + if (IsMob()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtSkeleton: + case cMonster::mtZombie: + case cMonster::mtWither: + case cMonster::mtZombiePigman: + { + a_TDI.RawDamage += 2.5 * SmiteLevel; + break; + } + } + } + } + else if (BaneOfArthropodsLevel > 0) + { + if (IsMob()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtSpider: + case cMonster::mtCaveSpider: + case cMonster::mtSilverfish: + { + a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + break; + } + } + } + } + + int FireAspectLevel = Enchantments.GetLevel(cEnchantments::enchFireAspect); + if (FireAspectLevel > 0) { + int BurnTicks = 3; + + if (FireAspectLevel > 1) + { + BurnTicks += 4 * (FireAspectLevel - 1); + } + + StartBurning(BurnTicks * 20); + } + + if (!Player->IsOnGround()) + { if ((a_TDI.DamageType == dtAttack) || (a_TDI.DamageType == dtArrowAttack)) { a_TDI.FinalDamage += 2; diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index fdc24689c..0fc0f0920 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -75,7 +75,6 @@ public: Arrow = NULL; return; } - a_Player->GetWorld()->BroadcastSoundEffect("random.bow", a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), 0.5, (float)Force); if (!a_Player->IsGameModeCreative()) { @@ -83,8 +82,19 @@ public: { a_Player->GetInventory().RemoveItem(cItem(E_ITEM_ARROW)); } + else + { + Arrow->SetPickupState(cArrowEntity::ePickupState::psNoPickup); + } + + a_Player->UseEquippedItem(); } + + if (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchFlame) > 0) + { + Arrow->StartBurning(100); + } } } ; -- cgit v1.2.3 From 1897f678f93bb038fdc4caf1fb2995a28ef8f92e Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 16:08:17 +0200 Subject: Added more enchantments and some fixes - Removed Debug messages - Added Punch enchantment effect - Added Silk Touch enchantment - Added Unbreaking enchantment effect --- src/Blocks/BlockHandler.cpp | 32 ++++++++++++++++++++++++++++---- src/Blocks/BlockIce.h | 24 ++++++++++++------------ src/Entities/ArrowEntity.cpp | 22 ++++++++++++++++++---- src/Entities/ArrowEntity.h | 1 + src/Entities/Entity.cpp | 25 ++++++++++++++++++++++--- src/Entities/Player.cpp | 20 ++++++++++++++++++++ 6 files changed, 101 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 52f7dd608..3c85a31e0 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -424,19 +424,43 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac cItems Pickups; NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (a_CanDrop) + // Thanks to daniel0916 + cPlayer * Player = (cPlayer *)a_Digger; + cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { - if (!a_DropVerbatim) + BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (Type == E_BLOCK_CAKE || Type == E_BLOCK_CARROTS || Type == E_BLOCK_COCOA_POD || Type == E_BLOCK_DOUBLE_STONE_SLAB || + Type == E_BLOCK_DOUBLE_WOODEN_SLAB || Type == E_BLOCK_FIRE || Type == E_BLOCK_FARMLAND || Type == E_BLOCK_MELON_STEM || + Type == E_BLOCK_MOB_SPAWNER || Type == E_BLOCK_NETHER_WART || Type == E_BLOCK_POTATOES || Type == E_BLOCK_PUMPKIN_STEM || + Type == E_BLOCK_SNOW || Type == E_BLOCK_SUGARCANE || Type == E_BLOCK_TALL_GRASS || Type == E_BLOCK_CROPS + ) { + // Silktouch can't be used for this blocks ConvertToPickups(Pickups, Meta); } else { - // TODO: Add a proper overridable function for this Pickups.Add(m_BlockType, 1, Meta); } } - + else + { + if (a_CanDrop) + { + if (!a_DropVerbatim) + { + ConvertToPickups(Pickups, Meta); + } + else + { + // TODO: Add a proper overridable function for this + Pickups.Add(m_BlockType, 1, Meta); + } + } + + } + // Allow plugins to modify the pickups: a_BlockPluginInterface.CallHookBlockToPickups(a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups); diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index c38630fe3..cfe1d179f 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -30,18 +30,18 @@ public: { return; } - - BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - if (!cBlockInfo::FullyOccupiesVoxel(BlockBelow) && !IsBlockLiquid(BlockBelow)) + + cEnchantments Enchantments = a_Player->GetInventory().GetEquippedItem().m_Enchantments; + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) == 0) { - return; + BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + if (!cBlockInfo::FullyOccupiesVoxel(BlockBelow) && !IsBlockLiquid(BlockBelow)) + { + return; + } + + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0); + // This is called later than the real destroying of this ice block } - - a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0); - // This is called later than the real destroying of this ice block } -} ; - - - - +} ; \ No newline at end of file diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index c4fd378fb..e71f30a66 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -109,18 +109,32 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } - LOGD("Arrow hit an entity"); int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { - LOGD("Arrow hit an entity 2"); int ExtraDamage = 0.25 * (PowerLevel + 1); Damage += ceil(ExtraDamage); } - a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); + + int KnockbackAmount = 1; + int PunchLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch); + if (PunchLevel > 0) + { + Vector3f LookVector = m_Creator->GetLookVector(); + Vector3f FinalSpeed = Vector3f(0, 0, 0); + switch (PunchLevel) + { + case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); + case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); + default: break; + } + a_EntityHit.SetSpeed(FinalSpeed); + } + + a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if (m_TicksLeftBurning > 0) + if ((m_TicksLeftBurning > 0 && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 2ea6e9fde..553bcb6e7 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -91,6 +91,7 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; + // Stores the creator from that arrow cEntity * m_Creator; /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 398f7703b..05bad3a78 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,7 +316,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - + // Thanks to daniel0916 cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); @@ -372,8 +372,27 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { BurnTicks += 4 * (FireAspectLevel - 1); } + if (!IsMob() && !IsSubmerged() && !IsSwimming()) + { + StartBurning(BurnTicks * 20); + } + else if (IsMob() && !IsSubmerged() && !IsSwimming()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtGhast: + case cMonster::mtZombiePigman: + case cMonster::mtMagmaCube: + { + + break; + }; + default:StartBurning(BurnTicks * 20); + } + } - StartBurning(BurnTicks * 20); + } if (!Player->IsOnGround()) @@ -410,7 +429,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case 2: AdditionalSpeed.Set(8, 0.3, 8); break; default: break; } - AddSpeed(a_TDI.Knockback + AdditionalSpeed); + SetSpeed(a_TDI.Knockback + AdditionalSpeed); } m_World->BroadcastEntityStatus(*this, esGenericHurt); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ab4ff3161..c1031907d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -17,6 +17,7 @@ #include "../Chunk.h" #include "../Items/ItemHandler.h" #include "../Vector3.h" +#include "../FastRandom.h" #include "../WorldStorage/StatSerializer.h" #include "../CompositeChat.h" @@ -1962,7 +1963,26 @@ void cPlayer::UseEquippedItem(int a_Amount) { return; } + cItem Item = GetEquippedItem(); + int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking); + if (UnbreakingLevel > 0) + { + int chance; + if (ItemCategory::IsArmor(Item.m_ItemType)) + { + chance = 60 + (40 / (UnbreakingLevel + 1)); + } + else + { + chance = 100 / (UnbreakingLevel + 1); + } + cFastRandom Random; + if (Random.NextInt(100) <= chance) + { + return; + } + } if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); -- cgit v1.2.3 From 07350de514cebd9009f5fbdb5774aa8f1266bdb3 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 16:47:33 +0200 Subject: Changed if for switch --- src/Blocks/BlockHandler.cpp | 33 ++++++++++++++++++++++----------- src/Blocks/BlockIce.h | 2 +- src/Entities/Entity.cpp | 5 ++--- 3 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 3c85a31e0..1d537b125 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -430,18 +430,29 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (Type == E_BLOCK_CAKE || Type == E_BLOCK_CARROTS || Type == E_BLOCK_COCOA_POD || Type == E_BLOCK_DOUBLE_STONE_SLAB || - Type == E_BLOCK_DOUBLE_WOODEN_SLAB || Type == E_BLOCK_FIRE || Type == E_BLOCK_FARMLAND || Type == E_BLOCK_MELON_STEM || - Type == E_BLOCK_MOB_SPAWNER || Type == E_BLOCK_NETHER_WART || Type == E_BLOCK_POTATOES || Type == E_BLOCK_PUMPKIN_STEM || - Type == E_BLOCK_SNOW || Type == E_BLOCK_SUGARCANE || Type == E_BLOCK_TALL_GRASS || Type == E_BLOCK_CROPS - ) + switch (Type) { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - } - else - { - Pickups.Add(m_BlockType, 1, Meta); + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + }; + default: Pickups.Add(m_BlockType, 1, Meta); } } else diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index cfe1d179f..47a84e5a7 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -44,4 +44,4 @@ public: // This is called later than the real destroying of this ice block } } -} ; \ No newline at end of file +} ; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 05bad3a78..4316b48e9 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -384,11 +384,10 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtGhast: case cMonster::mtZombiePigman: case cMonster::mtMagmaCube: - { - + { break; }; - default:StartBurning(BurnTicks * 20); + default: StartBurning(BurnTicks * 20); } } -- cgit v1.2.3 From 949aa2f3836cfa2b64ab5104b4b4103c4e2ad537 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 19 Aug 2014 17:34:11 +0200 Subject: cPlayer reads ranks from cRankManager. --- src/Bindings/ManualBindings.cpp | 93 +++++++++------ src/Entities/Player.cpp | 256 +++++++++------------------------------- src/Entities/Player.h | 53 +++++---- 3 files changed, 139 insertions(+), 263 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index c8eb5d138..a60408910 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1803,49 +1803,30 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) -static int tolua_cPlayer_GetGroups(lua_State * tolua_S) +static int tolua_cPlayer_GetPermissions(lua_State * tolua_S) { - cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); - - const cPlayer::GroupList & AllGroups = self->GetGroups(); + // Function signature: cPlayer:GetPermissions() -> {permissions-array} - lua_createtable(tolua_S, (int)AllGroups.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - cPlayer::GroupList::const_iterator iter = AllGroups.begin(); - while (iter != AllGroups.end()) + // Check the params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cPlayer") || + !L.CheckParamEnd (2) + ) { - const cGroup * Group = *iter; - tolua_pushusertype(tolua_S, (void *)Group, "const cGroup"); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; + return 0; } - return 1; -} - - - - -static int tolua_cPlayer_GetResolvedPermissions(lua_State * tolua_S) -{ - cPlayer * self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL); - - cPlayer::StringList AllPermissions = self->GetResolvedPermissions(); - - lua_createtable(tolua_S, (int)AllPermissions.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - cPlayer::StringList::iterator iter = AllPermissions.begin(); - while (iter != AllPermissions.end()) + // Get the params: + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) { - std::string & Permission = *iter; - lua_pushlstring(tolua_S, Permission.c_str(), Permission.length()); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + return 0; } + + // Push the permissions: + L.Push(self->GetPermissions()); return 1; } @@ -1902,6 +1883,40 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) +static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) +{ + // Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool + + // Check the params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cPlayer") || + !L.CheckParamString (2, 3) || + !L.CheckParamEnd (4) + ) + { + return 0; + } + + // Get the params: + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + return 0; + } + AString Permission, Template; + L.GetStackValues(2, Permission, Template); + + // Push the result of the match: + L.Push(self->PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); + return 1; +} + + + + + template < class OBJTYPE, void (OBJTYPE::*SetCallback)(cPluginLua * a_Plugin, int a_FnRef) @@ -3295,9 +3310,9 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlayer"); - tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups); - tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions); - tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); + tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions); + tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); + tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cLuaWindow"); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 4398a5bf3..423ca3317 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -59,7 +59,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_EnderChestContents(9, 3), m_CurrentWindow(NULL), m_InventoryWindow(NULL), - m_Color('-'), m_GameMode(eGameMode_NotSet), m_IP(""), m_ClientHandle(a_Client), @@ -1359,48 +1358,6 @@ void cPlayer::SetVisible(bool a_bVisible) -void cPlayer::AddToGroup( const AString & a_GroupName) -{ - cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName); - m_Groups.push_back( Group); - LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str()); - ResolveGroups(); - ResolvePermissions(); -} - - - - - -void cPlayer::RemoveFromGroup( const AString & a_GroupName) -{ - bool bRemoved = false; - for (GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr) - { - if ((*itr)->GetName().compare(a_GroupName) == 0) - { - m_Groups.erase( itr); - bRemoved = true; - break; - } - } - - if (bRemoved) - { - LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str()); - ResolveGroups(); - ResolvePermissions(); - } - else - { - LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str()); - } -} - - - - - bool cPlayer::HasPermission(const AString & a_Permission) { if (a_Permission.empty()) @@ -1409,33 +1366,18 @@ bool cPlayer::HasPermission(const AString & a_Permission) return true; } - AStringVector Split = StringSplit( a_Permission, "."); - PermissionMap Possibilities = m_ResolvedPermissions; - // Now search the namespaces - while (Possibilities.begin() != Possibilities.end()) + AStringVector Split = StringSplit(a_Permission, "."); + + // Iterate over all granted permissions; if any matches, then return success: + for (AStringVectorVector::const_iterator itr = m_SplitPermissions.begin(), end = m_SplitPermissions.end(); itr != end; ++itr) { - PermissionMap::iterator itr = Possibilities.begin(); - if (itr->second) + if (PermissionMatches(Split, *itr)) { - AStringVector OtherSplit = StringSplit( itr->first, "."); - if (OtherSplit.size() <= Split.size()) - { - unsigned int i; - for (i = 0; i < OtherSplit.size(); ++i) - { - if (OtherSplit[i].compare( Split[i]) != 0) - { - if (OtherSplit[i].compare("*") == 0) return true; // WildCard man!! WildCard! - break; - } - } - if (i == Split.size()) return true; - } + return true; } - Possibilities.erase( itr); - } + } // for itr - m_SplitPermissions[] - // Nothing that matched :( + // No granted permission matches return false; } @@ -1443,82 +1385,35 @@ bool cPlayer::HasPermission(const AString & a_Permission) -bool cPlayer::IsInGroup( const AString & a_Group) +bool cPlayer::PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template) { - for (GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr) + // Check the sub-items if they are the same or there's a wildcard: + size_t lenP = a_Permission.size(); + size_t lenT = a_Template.size(); + size_t minLen = std::min(lenP, lenT); + for (size_t i = 0; i < minLen; i++) { - if (a_Group.compare( (*itr)->GetName().c_str()) == 0) + if (a_Template[i] == "*") + { + // Has matched so far and now there's a wildcard in the template, so the permission matches: return true; - } - return false; -} - - - - - -void cPlayer::ResolvePermissions() -{ - m_ResolvedPermissions.clear(); // Start with an empty map - - // Copy all player specific permissions into the resolved permissions map - for (PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr) - { - m_ResolvedPermissions[ itr->first ] = itr->second; - } - - for (GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr) - { - const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions(); - for (cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr) + } + if (a_Permission[i] != a_Template[i]) { - m_ResolvedPermissions[ itr->first ] = itr->second; + // Found a mismatch + return false; } } -} - - - - -void cPlayer::ResolveGroups() -{ - // Clear resolved groups first - m_ResolvedGroups.clear(); - - // Get a complete resolved list of all groups the player is in - std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates - GroupList ToIterate; - for (GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr) - { - ToIterate.push_back( *GroupItr); - } - while (ToIterate.begin() != ToIterate.end()) + // So far all the sub-items have matched + // If the sub-item count is the same, then the permission matches: + if (lenP == lenT) { - cGroup* CurrentGroup = *ToIterate.begin(); - if (AllGroups.find( CurrentGroup) != AllGroups.end()) - { - LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", - GetName().c_str(), CurrentGroup->GetName().c_str() - ); - } - else - { - AllGroups[ CurrentGroup ] = true; - m_ResolvedGroups.push_back( CurrentGroup); // Add group to resolved list - const cGroup::GroupList & Inherits = CurrentGroup->GetInherits(); - for (cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr) - { - if (AllGroups.find( *itr) != AllGroups.end()) - { - LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str()); - continue; - } - ToIterate.push_back( *itr); - } - } - ToIterate.erase( ToIterate.begin()); + return true; } + + // There are more sub-items in either the permission or the template, not a match: + return false; } @@ -1527,17 +1422,14 @@ void cPlayer::ResolveGroups() AString cPlayer::GetColor(void) const { - if (m_Color != '-') - { - return cChatColor::Delimiter + m_Color; - } - - if (m_Groups.size() < 1) + if (m_MsgNameColorCode.empty() || (m_MsgNameColorCode == "-")) { - return cChatColor::White; + // Color has not been assigned, return an empty string: + return AString(); } - return (*m_Groups.begin())->GetColor(); + // Return the color, including the delimiter: + return cChatColor::Delimiter + m_MsgNameColorCode; } @@ -1653,48 +1545,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn) -void cPlayer::LoadPermissionsFromDisk() -{ - m_Groups.clear(); - m_Permissions.clear(); - - cIniFile IniFile; - if (IniFile.ReadFile("users.ini")) - { - AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default"); - AStringVector Split = StringSplitAndTrim(Groups, ","); - - for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) - { - if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr)) - { - LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str()); - } - AddToGroup(*itr); - } - - AString Color = IniFile.GetValue(GetName(), "Color", "-"); - if (!Color.empty()) - { - m_Color = Color[0]; - } - } - else - { - cGroupManager::GenerateDefaultUsersIni(IniFile); - IniFile.AddValue("Groups", GetName(), "Default"); - AddToGroup("Default"); - } - IniFile.WriteFile("users.ini"); - ResolvePermissions(); -} - - - - bool cPlayer::LoadFromDisk(cWorldPtr & a_World) { - LoadPermissionsFromDisk(); + LoadRank(); // Load from the UUID file: if (LoadFromFile(GetUUIDFileName(m_UUID), a_World)) @@ -1928,26 +1781,6 @@ bool cPlayer::SaveToDisk() -cPlayer::StringList cPlayer::GetResolvedPermissions() -{ - StringList Permissions; - - const PermissionMap& ResolvedPermissions = m_ResolvedPermissions; - for (PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr) - { - if (itr->second) - { - Permissions.push_back( itr->first); - } - } - - return Permissions; -} - - - - - void cPlayer::UseEquippedItem(int a_Amount) { if (IsGameModeCreative()) // No damage in creative @@ -2206,6 +2039,27 @@ void cPlayer::ApplyFoodExhaustionFromMovement() +void cPlayer::LoadRank(void) +{ + // Load the values from cRankManager: + cRankManager & RankMgr = cRoot::Get()->GetRankManager(); + m_Rank = RankMgr.GetPlayerRankName(m_UUID); + m_Permissions = RankMgr.GetPlayerPermissions(m_UUID); + RankMgr.GetPlayerMsgVisuals(m_UUID, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); + + // Break up the individual permissions on each dot, into m_SplitPermissions: + m_SplitPermissions.clear(); + m_SplitPermissions.reserve(m_Permissions.size()); + for (AStringVector::const_iterator itr = m_Permissions.begin(), end = m_Permissions.end(); itr != end; ++itr) + { + m_SplitPermissions.push_back(StringSplit(*itr, ".")); + } // for itr - m_Permissions[] +} + + + + + void cPlayer::Detach() { super::Detach(); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index d3ed1ef9d..0ae014eeb 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -236,24 +236,20 @@ public: // tolua_end - typedef std::list< cGroup* > GroupList; - typedef std::list< std::string > StringList; + bool HasPermission(const AString & a_Permission); // tolua_export - /** Adds a player to existing group or creates a new group when it doesn't exist */ - void AddToGroup( const AString & a_GroupName); // tolua_export - - /** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */ - void RemoveFromGroup( const AString & a_GroupName); // tolua_export - - bool HasPermission( const AString & a_Permission); // tolua_export - const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS << - StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << - bool IsInGroup( const AString & a_Group); // tolua_export + /** Returns true iff a_Permission matches the a_Template. + A match is defined by either being exactly the same, or each sub-item matches until there's a wildcard in a_Template. + Ie. {"a", "b", "c"} matches {"a", "b", "*"} but doesn't match {"a", "b"} */ + static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template); // Exported in ManualBindings with AString params + + /** Returns all the permissions that the player has assigned to them. */ + const AStringVector & GetPermissions(void) { return m_Permissions; } // Exported in ManualBindings.cpp // tolua_begin - /** Returns the full color code to use for this player, based on their primary group or set in m_Color. - The returned value includes the cChatColor::Delimiter. */ + /** Returns the full color code to use for this player, based on their rank. + The returned value either is empty, or includes the cChatColor::Delimiter. */ AString GetColor(void) const; /** tosses the item in the selected hotbar slot */ @@ -347,8 +343,6 @@ public: */ bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World); - void LoadPermissionsFromDisk(void); // tolua_export - const AString & GetLoadedWorldName() { return m_LoadedWorldName; } void UseEquippedItem(int a_Amount = 1); @@ -424,6 +418,11 @@ public: // tolua_end + /** (Re)loads the rank and permissions from the cRankManager. + Expects the m_UUID member to be valid. + Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */ + void LoadRank(void); + // cEntity overrides: virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsSprinting(void) const { return m_IsSprinting; } @@ -432,12 +431,22 @@ public: virtual void Detach(void); protected: - typedef std::map< std::string, bool > PermissionMap; - PermissionMap m_ResolvedPermissions; - PermissionMap m_Permissions; - GroupList m_ResolvedGroups; - GroupList m_Groups; + typedef std::vector > AStringVectorVector; + + /** The name of the rank assigned to this player. */ + AString m_Rank; + + /** All the permissions that this player has, based on their rank. */ + AStringVector m_Permissions; + + /** All the permissions that this player has, based on their rank, split into individual dot-delimited parts. + This is used mainly by the HasPermission() function to optimize the lookup. */ + AStringVectorVector m_SplitPermissions; + + // Message visuals: + AString m_MsgPrefix, m_MsgSuffix; + AString m_MsgNameColorCode; AString m_PlayerName; AString m_LoadedWorldName; @@ -482,8 +491,6 @@ protected: /** The player's last saved bed position */ Vector3i m_LastBedPos; - char m_Color; - eGameMode m_GameMode; AString m_IP; -- cgit v1.2.3 From 596203e692e6322c7f989b1625cbe03dc1eb6a6c Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 17:57:32 +0200 Subject: Fixes - Changed m_TicksLeftBurning > 0 for IsOnFire() - Tried to do the changes in BlockHandler.cpp - Removed m_Creator in ArrowEntity - Added m_Enchantments in ProjectileEntity CreatorData - Added blank lines between functions --- src/Blocks/BlockHandler.cpp | 70 +++++++++++++++++++-------------------- src/Entities/ArrowEntity.cpp | 15 +++++---- src/Entities/ArrowEntity.h | 3 -- src/Entities/ProjectileEntity.cpp | 5 +-- src/Entities/ProjectileEntity.h | 6 ++-- src/Items/ItemBow.h | 2 +- 6 files changed, 51 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 1d537b125..d6be99f83 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -427,49 +427,49 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac // Thanks to daniel0916 cPlayer * Player = (cPlayer *)a_Digger; cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; - if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) - { - BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - switch (Type) - { - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_CROPS: - { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - }; - default: Pickups.Add(m_BlockType, 1, Meta); - } - } - else + + if (a_CanDrop) { - if (a_CanDrop) + if (!a_DropVerbatim) { - if (!a_DropVerbatim) + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { - ConvertToPickups(Pickups, Meta); + switch (m_BlockType) + { + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + break; + }; + default: Pickups.Add(m_BlockType, 1, Meta); + } } else { - // TODO: Add a proper overridable function for this - Pickups.Add(m_BlockType, 1, Meta); + ConvertToPickups(Pickups, Meta); } } - + else + { + // TODO: Add a proper overridable function for this + Pickups.Add(m_BlockType, 1, Meta); + } } // Allow plugins to modify the pickups: diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index e71f30a66..12149b297 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -18,7 +18,6 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), - m_Creator(a_Creator), m_HitBlockPos(Vector3i(0, 0, 0)) { SetSpeed(a_Speed); @@ -44,7 +43,6 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), - m_Creator(&a_Player), m_HitBlockPos(0, 0, 0) { if (a_Player.IsGameModeCreative()) @@ -70,6 +68,9 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const } + + + void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001)) @@ -90,7 +91,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (m_TicksLeftBurning > 0)) + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (IsOnFire())) { m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); m_World->SpawnPrimedTNT(X, Y, Z); @@ -110,7 +111,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } - int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); + int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { int ExtraDamage = 0.25 * (PowerLevel + 1); @@ -118,10 +119,10 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) } int KnockbackAmount = 1; - int PunchLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch); + int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch); if (PunchLevel > 0) { - Vector3f LookVector = m_Creator->GetLookVector(); + Vector3f LookVector = Vector3d(0, 0, 0); Vector3f FinalSpeed = Vector3f(0, 0, 0); switch (PunchLevel) { @@ -134,7 +135,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if ((m_TicksLeftBurning > 0 && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) + if ((IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 553bcb6e7..a1e7a17e7 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -91,9 +91,6 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; - // Stores the creator from that arrow - cEntity * m_Creator; - /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air Vector3i m_HitBlockPos; diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 43023ec28..acc9bd674 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -222,7 +222,8 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a m_ProjectileKind(a_Kind), m_CreatorData( ((a_Creator != NULL) ? a_Creator->GetUniqueID() : -1), - ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : "") + ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""), + ((a_Creator != NULL) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments()) ), m_IsInGround(false) { @@ -235,7 +236,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) : super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height), m_ProjectileKind(a_Kind), - m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : ""), + m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments), m_IsInGround(false) { SetSpeed(a_Speed); diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 0ebc32f36..58dc38702 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -94,14 +94,16 @@ protected: */ struct CreatorData { - CreatorData(int a_UniqueID, const AString & a_Name) : + CreatorData(int a_UniqueID, const AString & a_Name, cEnchantments a_Enchantments) : m_UniqueID(a_UniqueID), - m_Name(a_Name) + m_Name(a_Name), + m_Enchantments(a_Enchantments) { } const int m_UniqueID; AString m_Name; + cEnchantments m_Enchantments; }; /** The type of projectile I am */ diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index 0fc0f0920..f29cc5d59 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -84,7 +84,7 @@ public: } else { - Arrow->SetPickupState(cArrowEntity::ePickupState::psNoPickup); + Arrow->SetPickupState(cArrowEntity::psNoPickup); } -- cgit v1.2.3 From 5008eb8c8348ad2664158a8a815ef6851d874367 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 18:40:42 +0200 Subject: Changed if in BlockHandler --- src/Blocks/BlockHandler.cpp | 7 ++----- src/Entities/Entity.cpp | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index d6be99f83..2238a68a0 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -424,15 +424,12 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac cItems Pickups; NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - // Thanks to daniel0916 - cPlayer * Player = (cPlayer *)a_Digger; - cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; - if (a_CanDrop) { if (!a_DropVerbatim) { - if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) + cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && (a_Digger->IsPlayer())) { switch (m_BlockType) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 4316b48e9..54e4cf4f5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,7 +316,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - // Thanks to daniel0916 cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); -- cgit v1.2.3 From b5ffe06f884221f98407910bdd30baf533d84970 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 19 Aug 2014 22:14:37 +0200 Subject: Code formatting fixes. --- src/Blocks/BlockBigFlower.h | 6 +++--- src/Blocks/BlockCake.h | 2 +- src/Blocks/BlockDirt.h | 2 +- src/Blocks/BlockFarmland.h | 5 +---- src/Blocks/BlockFenceGate.h | 1 + src/Blocks/BlockFire.h | 25 ++++++++++++++--------- src/Blocks/BlockFlower.h | 2 +- src/Blocks/BlockGlowstone.h | 6 +++--- src/Blocks/BlockHandler.cpp | 6 ++---- src/Blocks/BlockMelon.h | 4 ++-- src/Blocks/BlockNewLeaves.h | 42 -------------------------------------- src/Blocks/BlockNote.h | 13 ------------ src/Blocks/BlockOre.h | 40 ++++++++++-------------------------- src/Blocks/BlockPlanks.h | 3 +-- src/Blocks/BlockPortal.h | 8 ++++---- src/Blocks/BlockPressurePlate.h | 4 ++-- src/Blocks/BlockQuartz.h | 1 + src/Blocks/BlockRedstone.h | 4 ++-- src/Blocks/BlockRedstoneRepeater.h | 6 +++--- src/Blocks/BlockStairs.h | 20 +++++++++--------- src/Blocks/BlockSugarcane.h | 1 + src/Blocks/BlockTorch.h | 4 ++-- src/Blocks/BlockTrapdoor.h | 9 ++++---- src/Blocks/BlockTripwireHook.h | 10 ++++----- src/Blocks/BlockVine.h | 6 +++--- src/Chunk.cpp | 1 + src/Items/ItemGoldenApple.h | 2 +- src/Items/ItemShovel.h | 1 - src/World.cpp | 1 + 29 files changed, 83 insertions(+), 152 deletions(-) delete mode 100644 src/Blocks/BlockNewLeaves.h delete mode 100644 src/Blocks/BlockNote.h (limited to 'src') diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 0b6ac9d8a..72e552dee 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -37,7 +37,7 @@ public: { NIBBLETYPE Meta = a_BlockMeta & 0x7; - if ((Meta == 2) || (Meta == 3)) + if ((Meta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) || (Meta == E_META_BIG_FLOWER_LARGE_FERN)) { return; } @@ -63,11 +63,11 @@ public: if (r1.randInt(10) == 5) { cItems Pickups; - if (FlowerMeta == 2) + if (FlowerMeta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) { Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1); } - else if (FlowerMeta == 3) + else if (FlowerMeta == E_META_BIG_FLOWER_LARGE_FERN) { Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2); } diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index 36e133388..f05f468e5 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -19,7 +19,7 @@ public: { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (!a_Player->Feed(2, 0.1)) + if (!a_Player->Feed(2, 0.4)) { return; } diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 2d4fccbac..d458c6062 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -81,7 +81,7 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta)) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h index ed0592acd..bb624e54f 100644 --- a/src/Blocks/BlockFarmland.h +++ b/src/Blocks/BlockFarmland.h @@ -54,10 +54,7 @@ public: BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); for (size_t i = 0; i < NumBlocks; i++) { - if ( - (BlockTypes[i] == E_BLOCK_WATER) || - (BlockTypes[i] == E_BLOCK_STATIONARY_WATER) - ) + if (IsBlockWater(BlockTypes[i])) { Found = true; break; diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index 433531275..ae99a4f94 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -35,6 +35,7 @@ public: NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw()); OldMetaData ^= 4; // Toggle the gate + if ((OldMetaData & 1) == (NewMetaData & 1)) { // Standing in front of the gate - apply new direction diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index f52825362..c6a3e62cf 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -60,8 +60,8 @@ public: return "step.wood"; } - /// Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border - /// Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding + /** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border + Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */ int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0) { if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN) @@ -91,13 +91,12 @@ public: return newY; } } - else { return 0; } } return 0; } - /// Evaluates if coords have a valid border on top, based on MaxY + /** Evaluates if coords have a valid border on top, based on MaxY */ bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface) { for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners @@ -149,8 +148,8 @@ public: return; } - /// Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable - /// Takes coordinates of base block and Y coord of target obsidian ceiling + /** Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable + Takes coordinates of base block and Y coord of target obsidian ceiling */ bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface) { Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction) @@ -168,7 +167,8 @@ public: { return false; // Not valid slice, no portal can be formed } - } XZP = X1 - 1; // Set boundary of frame interior + } + XZP = X1 - 1; // Set boundary of frame interior for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM) { int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY); @@ -182,7 +182,9 @@ public: { return false; } - } XZM = X2 + 1; // Set boundary, see previous + } + XZM = X2 + 1; // Set boundary, see previous + return (FoundFrameXP && FoundFrameXM); } @@ -204,7 +206,8 @@ public: { return false; } - } XZP = Z1 - 1; + } + XZP = Z1 - 1; for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--) { int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY); @@ -218,7 +221,9 @@ public: { return false; } - } XZM = Z2 + 1; + } + XZM = Z2 + 1; + return (FoundFrameZP && FoundFrameZM); } }; diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h index e8fd4c7f6..6f64c062b 100644 --- a/src/Blocks/BlockFlower.h +++ b/src/Blocks/BlockFlower.h @@ -19,7 +19,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } diff --git a/src/Blocks/BlockGlowstone.h b/src/Blocks/BlockGlowstone.h index 6c198efc4..d1353e29a 100644 --- a/src/Blocks/BlockGlowstone.h +++ b/src/Blocks/BlockGlowstone.h @@ -15,13 +15,13 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 - MTRand r1; - a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + r1.randInt(2)), 0)); + cFastRandom Random; + a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + Random.NextInt(3)), 0)); } } ; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 52f7dd608..028277e4c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -45,13 +45,11 @@ #include "BlockLadder.h" #include "BlockLeaves.h" #include "BlockLilypad.h" -#include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" #include "BlockMushroom.h" #include "BlockMycelium.h" #include "BlockNetherWart.h" -#include "BlockNote.h" #include "BlockOre.h" #include "BlockPiston.h" #include "BlockPlanks.h" @@ -251,9 +249,9 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType); case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_NEW_LEAVES: return new cBlockNewLeavesHandler (a_BlockType); + case E_BLOCK_NEW_LEAVES: return new cBlockLeavesHandler (a_BlockType); case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType); - case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); + case E_BLOCK_NOTE_BLOCK: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler; case E_BLOCK_PLANKS: return new cBlockPlanksHandler (a_BlockType); diff --git a/src/Blocks/BlockMelon.h b/src/Blocks/BlockMelon.h index 2f7d9a461..60202d66e 100644 --- a/src/Blocks/BlockMelon.h +++ b/src/Blocks/BlockMelon.h @@ -19,8 +19,8 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - MTRand r1; - a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0)); + cFastRandom Random; + a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + Random.NextInt(5)), 0)); } diff --git a/src/Blocks/BlockNewLeaves.h b/src/Blocks/BlockNewLeaves.h deleted file mode 100644 index 5a267e8c6..000000000 --- a/src/Blocks/BlockNewLeaves.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "BlockHandler.h" -#include "BlockLeaves.h" -#include "../World.h" - - - - - - -class cBlockNewLeavesHandler : - public cBlockLeavesHandler -{ -public: - cBlockNewLeavesHandler(BLOCKTYPE a_BlockType) - : cBlockLeavesHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - MTRand rand; - - // Only the first 2 bits contain the display information, the others are for growing - if (rand.randInt(5) == 0) - { - a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, (a_BlockMeta & 3) + 4)); - } - } - - - void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - } -} ; - - - - - diff --git a/src/Blocks/BlockNote.h b/src/Blocks/BlockNote.h deleted file mode 100644 index fef38d845..000000000 --- a/src/Blocks/BlockNote.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "BlockHandler.h" -#include "BlockEntity.h" - -class cBlockNoteHandler : public cBlockEntityHandler -{ -public: - cBlockNoteHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) - { - } - -}; diff --git a/src/Blocks/BlockOre.h b/src/Blocks/BlockOre.h index 9684dbb19..0067d475f 100644 --- a/src/Blocks/BlockOre.h +++ b/src/Blocks/BlockOre.h @@ -2,7 +2,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" #include "../World.h" @@ -20,58 +19,41 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - short ItemType = m_BlockType; - char Count = 1; - short Meta = 0; - - MTRand r1; + cFastRandom Random; + switch (m_BlockType) { case E_BLOCK_LAPIS_ORE: { - ItemType = E_ITEM_DYE; - Count = 4 + (char)r1.randInt(4); - Meta = 4; + a_Pickups.push_back(cItem(E_ITEM_DYE, (char)(4 + Random.NextInt(5)), 4)); break; } case E_BLOCK_REDSTONE_ORE: case E_BLOCK_REDSTONE_ORE_GLOWING: { - Count = 4 + (char)r1.randInt(1); - break; - } - default: - { - Count = 1; + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, (char)(4 + Random.NextInt(2)), 0)); break; } - } - - switch (m_BlockType) - { case E_BLOCK_DIAMOND_ORE: { - ItemType = E_ITEM_DIAMOND; - break; - } - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - ItemType = E_ITEM_REDSTONE_DUST; + a_Pickups.push_back(cItem(E_ITEM_DIAMOND)); break; } case E_BLOCK_EMERALD_ORE: { - ItemType = E_ITEM_EMERALD; + a_Pickups.push_back(cItem(E_ITEM_EMERALD)); break; } case E_BLOCK_COAL_ORE: { - ItemType = E_ITEM_COAL; + a_Pickups.push_back(cItem(E_ITEM_COAL)); break; } + default: + { + ASSERT(!"Unhandled ore!"); + } } - a_Pickups.push_back(cItem(ItemType, Count, Meta)); } } ; diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h index de84ed319..4c5bb4860 100644 --- a/src/Blocks/BlockPlanks.h +++ b/src/Blocks/BlockPlanks.h @@ -24,8 +24,7 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); - a_BlockMeta = Meta; + a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); return true; } diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index fc74e89d0..8fac2a126 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -36,7 +36,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - return; // No pickups + // No pickups } virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override @@ -47,15 +47,15 @@ public: return; } - int PosX = a_Chunk.GetPosX() * 16 + a_RelX; - int PosZ = a_Chunk.GetPosZ() * 16 + a_RelZ; + int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX; + int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ; a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman); } virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - if ((a_RelY - 1 < 0) || (a_RelY + 1 > cChunkDef::Height)) + if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height)) { return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1 } diff --git a/src/Blocks/BlockPressurePlate.h b/src/Blocks/BlockPressurePlate.h index adec36eb6..a5c34a776 100644 --- a/src/Blocks/BlockPressurePlate.h +++ b/src/Blocks/BlockPressurePlate.h @@ -17,7 +17,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } @@ -29,7 +29,7 @@ public: } BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); - return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow)); + return (cBlockInfo::IsSolid(BlockBelow)); } } ; diff --git a/src/Blocks/BlockQuartz.h b/src/Blocks/BlockQuartz.h index 2ce7e71e4..edc4fb9c5 100644 --- a/src/Blocks/BlockQuartz.h +++ b/src/Blocks/BlockQuartz.h @@ -25,6 +25,7 @@ public: { a_BlockType = m_BlockType; NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); + if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block. { a_BlockMeta = Meta; diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index a898c9acb..37d61ed73 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -26,8 +26,8 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 - a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); + // Reset meta to zero + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1, 0)); } } ; diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 4c8a6a087..4b18add12 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -23,7 +23,7 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw()); @@ -46,7 +46,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1, 0)); } @@ -59,7 +59,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); + return ((a_RelY > 0) && cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index a7ccf1714..417969a82 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -16,8 +16,8 @@ public: { } - - + + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -53,8 +53,8 @@ public: } return true; } - - + + virtual const char * GetStepSound(void) override { if ( @@ -64,7 +64,7 @@ public: (m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) || (m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) || (m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS) - ) + ) { return "step.wood"; } @@ -72,17 +72,20 @@ public: return "step.stone"; } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } + virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override { return true; } - + + static NIBBLETYPE RotationToMetaData(double a_Rotation) { a_Rotation += 90 + 45; // So its not aligned with axis @@ -108,14 +111,11 @@ public: } } - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { // Toggle bit 3: return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); } - - } ; diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h index 84d3b2e7d..5902c791b 100644 --- a/src/Blocks/BlockSugarcane.h +++ b/src/Blocks/BlockSugarcane.h @@ -29,6 +29,7 @@ public: { return false; } + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) { case E_BLOCK_DIRT: diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index c73118870..df5574d5d 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -126,7 +126,7 @@ public: (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) && (Face == BLOCK_FACE_TOP) - ) + ) { return Face; } @@ -162,7 +162,7 @@ public: (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) - ) + ) { // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' // No need to check for upright orientation, it was done when the torch was placed diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 6a36ab874..a6327b5c2 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -23,7 +23,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } @@ -53,7 +53,7 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; a_BlockMeta = BlockFaceToMetaData(a_BlockFace); @@ -103,9 +103,10 @@ public: a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); - BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + BLOCKTYPE BlockIsOn; + a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); + return ((a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn)); } }; diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h index f849fb8ad..4f9d79483 100644 --- a/src/Blocks/BlockTripwireHook.h +++ b/src/Blocks/BlockTripwireHook.h @@ -21,10 +21,9 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; - a_BlockMeta = DirectionToMetadata(a_BlockFace); return true; @@ -56,7 +55,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0)); } @@ -66,9 +65,10 @@ public: a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true); - BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + BLOCKTYPE BlockIsOn; + a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); + return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn)); } virtual const char * GetStepSound(void) override diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 1e1f6d8d2..578224c61 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -46,7 +46,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_BLOCK_VINES, 1, 0)); } @@ -80,7 +80,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType); + return ((a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType)); } @@ -182,7 +182,7 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread)) { a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 7bdf4196d..116c0f3a0 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #ifndef _WIN32 diff --git a/src/Items/ItemGoldenApple.h b/src/Items/ItemGoldenApple.h index 4e1096e65..02ac0202c 100644 --- a/src/Items/ItemGoldenApple.h +++ b/src/Items/ItemGoldenApple.h @@ -29,7 +29,7 @@ public: a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 100, 1); // When the apple is a 'notch apple', give extra effects: - if (a_Item->m_ItemDamage > 0) + if (a_Item->m_ItemDamage >= E_META_GOLDEN_APPLE_ENCHANTED) { a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 600, 4); a_Player->AddEntityEffect(cEntityEffect::effResistance, 6000, 0); diff --git a/src/Items/ItemShovel.h b/src/Items/ItemShovel.h index 7d5760fa9..cd235678d 100644 --- a/src/Items/ItemShovel.h +++ b/src/Items/ItemShovel.h @@ -19,7 +19,6 @@ public: cItemShovelHandler(int a_ItemType) : cItemHandler(a_ItemType) { - } virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override diff --git a/src/World.cpp b/src/World.cpp index b357b8a23..2027e215a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BlockID.h" -- cgit v1.2.3 From 67fc19301e4909101c6f2f31cb5d49413fe47d42 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 12:14:56 +0200 Subject: Removed old classes from the CMakeLists.txt --- src/Blocks/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index 05b7bfab4..9f971a8bd 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -57,8 +57,6 @@ SET (HDRS BlockMushroom.h BlockMycelium.h BlockNetherWart.h - BlockNewLeaves.h - BlockNote.h BlockOre.h BlockPiston.h BlockPlanks.h -- cgit v1.2.3 From 228dd61995a404b6c59832bf8b0f8375374c8acc Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 16:01:30 +0200 Subject: Added HOOK_SERVER_PING --- src/Bindings/LuaState_Call.inc | 847 ++++++++++++++++++++++++++++++++++++++ src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 +- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 +- src/Bindings/PluginManager.h | 2 +- src/Protocol/Protocol17x.cpp | 99 +++-- src/Protocol/ProtocolRecognizer.h | 2 +- 8 files changed, 926 insertions(+), 36 deletions(-) create mode 100644 src/Bindings/LuaState_Call.inc (limited to 'src') diff --git a/src/Bindings/LuaState_Call.inc b/src/Bindings/LuaState_Call.inc new file mode 100644 index 000000000..810b0551b --- /dev/null +++ b/src/Bindings/LuaState_Call.inc @@ -0,0 +1,847 @@ +// LuaState_Call.inc + +// This file is auto-generated by gen_LuaState_Call.lua +// Make changes to the generator instead of to this file! + +// This file contains the various overloads for the cLuaState::Call() function +// Each overload handles a different number of parameters / return values + + + + + +/** Call the specified 0-param 0-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function) +{ + if (!PushFunction(a_Function)) + { + return false; + } + if (!CallFunction(0)) + { + return false; + } + return true; +} + + + + + +/** Call the specified 1-param 0-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1) +{ + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + if (!CallFunction(0)) + { + return false; + } + return true; +} + + + + + +/** Call the specified 2-param 0-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2) +{ + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + if (!CallFunction(0)) + { + return false; + } + return true; +} + + + + + +/** Call the specified 3-param 0-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3) +{ + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + if (!CallFunction(0)) + { + return false; + } + return true; +} + + + + + +/** Call the specified 4-param 0-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4) +{ + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + if (!CallFunction(0)) + { + return false; + } + return true; +} + + + + + +/** Call the specified 0-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 1-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 2-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 3-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 4-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 5-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 6-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 7-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 8-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 9-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + Push(a_Param9); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 10-param 1-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, ParamT10 a_Param10, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + Push(a_Param9); + Push(a_Param10); + if (!CallFunction(1)) + { + return false; + } + GetStackValue(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; +} + + + + + +/** Call the specified 0-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 1-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 2-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 3-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 4-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 5-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 6-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 7-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 8-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 9-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + Push(a_Param9); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} + + + + + +/** Call the specified 7-param 3-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + if (!CallFunction(3)) + { + return false; + } + GetStackValue(-3, a_Ret1); + GetStackValue(-2, a_Ret2); + GetStackValue(-1, a_Ret3); + lua_pop(m_LuaState, 3); + return true; +} + + + + + +/** Call the specified 8-param 3-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + if (!CallFunction(3)) + { + return false; + } + GetStackValue(-3, a_Ret1); + GetStackValue(-2, a_Ret2); + GetStackValue(-1, a_Ret3); + lua_pop(m_LuaState, 3); + return true; +} + + + + + +/** Call the specified 4-param 5-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + if (!CallFunction(5)) + { + return false; + } + GetStackValue(-5, a_Ret1); + GetStackValue(-4, a_Ret2); + GetStackValue(-3, a_Ret3); + GetStackValue(-2, a_Ret4); + GetStackValue(-1, a_Ret5); + lua_pop(m_LuaState, 5); + return true; +} + + + + + +/** Call the specified 9-param 5-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + Push(a_Param4); + Push(a_Param5); + Push(a_Param6); + Push(a_Param7); + Push(a_Param8); + Push(a_Param9); + if (!CallFunction(5)) + { + return false; + } + GetStackValue(-5, a_Ret1); + GetStackValue(-4, a_Ret2); + GetStackValue(-3, a_Ret3); + GetStackValue(-2, a_Ret4); + GetStackValue(-1, a_Ret5); + lua_pop(m_LuaState, 5); + return true; +} + + + + + diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 6f05af51b..fef86822d 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -91,7 +91,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; - virtual bool OnServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; + virtual bool OnServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 066e050d6..dbe2e7a0d 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1193,14 +1193,14 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity -bool cPluginLua::OnServerPing(const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginLua::OnServerPing(AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Username, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); + m_LuaState.Call((int)(**itr), a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 2d98477f0..185b2a887 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -117,7 +117,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; - virtual bool OnServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; + virtual bool OnServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index b9d28205d..fcbb446c1 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1189,14 +1189,14 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil -bool cPluginManager::CallHookServerPing(const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginManager::CallHookServerPing(AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { FIND_HOOK(HOOK_SERVER_PING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnServerPing(a_Username, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) + if ((*itr)->OnServerPing(a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 104e4c7a9..db8a2ca64 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -226,7 +226,7 @@ public: bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); - bool CallHookServerPing (const AString & a_Username, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); + bool CallHookServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 1f8ca00bb..31a140c73 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -41,6 +41,8 @@ Implements the 1.7.x protocol classes: #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" +#include "Bindings/PluginManager.h" +#include "lua/src/llex.h" @@ -1715,21 +1717,41 @@ void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) { - // Send the response: - AString Response = "{\"version\":{\"name\":\"1.7.2\", \"protocol\":4}, \"players\":{"; cServer * Server = cRoot::Get()->GetServer(); - AppendPrintf(Response, "\"max\":%u, \"online\":%u, \"sample\":[]},", - Server->GetMaxPlayers(), - Server->GetNumPlayers() - ); - AppendPrintf(Response, "\"description\":{\"text\":\"%s\"},", - Server->GetDescription().c_str() - ); - AppendPrintf(Response, "\"favicon\": \"data:image/png;base64,%s\"", - Server->GetFaviconData().c_str() - ); - Response.append("}"); - + AString Motd = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(Motd, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "1.7.2"; + Version["protocol"] = 4; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = Motd.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + Json::StyledWriter Writer; + AString Response = Writer.write(ResponseValue); + cPacketizer Pkt(*this, 0x00); // Response packet Pkt.WriteString(Response); } @@ -3065,20 +3087,41 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) { - // Send the response: - AString Response = "{\"version\": {\"name\": \"1.7.6\", \"protocol\":5}, \"players\": {"; - AppendPrintf(Response, "\"max\": %u, \"online\": %u, \"sample\": []},", - cRoot::Get()->GetServer()->GetMaxPlayers(), - cRoot::Get()->GetServer()->GetNumPlayers() - ); - AppendPrintf(Response, "\"description\": {\"text\": \"%s\"},", - cRoot::Get()->GetServer()->GetDescription().c_str() - ); - AppendPrintf(Response, "\"favicon\": \"data:image/png;base64,%s\"", - cRoot::Get()->GetServer()->GetFaviconData().c_str() - ); - Response.append("}"); - + cServer * Server = cRoot::Get()->GetServer(); + AString Motd = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(Motd, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "1.7.6"; + Version["protocol"] = 5; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = Motd.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + Json::StyledWriter Writer; + AString Response = Writer.write(ResponseValue); + cPacketizer Pkt(*this, 0x00); // Response packet Pkt.WriteString(Response); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 65829ef73..796464202 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -18,7 +18,7 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9" +#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10" #define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5" -- cgit v1.2.3 From 2cca4d70c8b3908bcd692fffb937c0fa6b5b29a3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 16:04:18 +0200 Subject: Cleaned up code. --- src/Bindings/LuaState_Call.inc | 847 ------------------------------------- src/Bindings/gen_LuaState_Call.lua | 1 + src/Protocol/Protocol17x.cpp | 1 - 3 files changed, 1 insertion(+), 848 deletions(-) delete mode 100644 src/Bindings/LuaState_Call.inc (limited to 'src') diff --git a/src/Bindings/LuaState_Call.inc b/src/Bindings/LuaState_Call.inc deleted file mode 100644 index 810b0551b..000000000 --- a/src/Bindings/LuaState_Call.inc +++ /dev/null @@ -1,847 +0,0 @@ -// LuaState_Call.inc - -// This file is auto-generated by gen_LuaState_Call.lua -// Make changes to the generator instead of to this file! - -// This file contains the various overloads for the cLuaState::Call() function -// Each overload handles a different number of parameters / return values - - - - - -/** Call the specified 0-param 0-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function) -{ - if (!PushFunction(a_Function)) - { - return false; - } - if (!CallFunction(0)) - { - return false; - } - return true; -} - - - - - -/** Call the specified 1-param 0-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1) -{ - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - if (!CallFunction(0)) - { - return false; - } - return true; -} - - - - - -/** Call the specified 2-param 0-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2) -{ - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - if (!CallFunction(0)) - { - return false; - } - return true; -} - - - - - -/** Call the specified 3-param 0-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3) -{ - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - if (!CallFunction(0)) - { - return false; - } - return true; -} - - - - - -/** Call the specified 4-param 0-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4) -{ - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - if (!CallFunction(0)) - { - return false; - } - return true; -} - - - - - -/** Call the specified 0-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 1-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 2-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 3-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 4-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 5-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 6-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 7-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 8-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 9-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - Push(a_Param9); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 10-param 1-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, ParamT10 a_Param10, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - Push(a_Param9); - Push(a_Param10); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; -} - - - - - -/** Call the specified 0-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 1-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 2-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 3-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 4-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 5-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 6-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 7-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 8-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 9-param 2-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - Push(a_Param9); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; -} - - - - - -/** Call the specified 7-param 3-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - if (!CallFunction(3)) - { - return false; - } - GetStackValue(-3, a_Ret1); - GetStackValue(-2, a_Ret2); - GetStackValue(-1, a_Ret3); - lua_pop(m_LuaState, 3); - return true; -} - - - - - -/** Call the specified 8-param 3-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - if (!CallFunction(3)) - { - return false; - } - GetStackValue(-3, a_Ret1); - GetStackValue(-2, a_Ret2); - GetStackValue(-1, a_Ret3); - lua_pop(m_LuaState, 3); - return true; -} - - - - - -/** Call the specified 4-param 5-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - if (!CallFunction(5)) - { - return false; - } - GetStackValue(-5, a_Ret1); - GetStackValue(-4, a_Ret2); - GetStackValue(-3, a_Ret3); - GetStackValue(-2, a_Ret4); - GetStackValue(-1, a_Ret5); - lua_pop(m_LuaState, 5); - return true; -} - - - - - -/** Call the specified 9-param 5-return Lua function: -Returns true if call succeeded, false if there was an error. */ -template -bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, ParamT4 a_Param4, ParamT5 a_Param5, ParamT6 a_Param6, ParamT7 a_Param7, ParamT8 a_Param8, ParamT9 a_Param9, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) -{ - UNUSED(a_RetMark); - if (!PushFunction(a_Function)) - { - return false; - } - Push(a_Param1); - Push(a_Param2); - Push(a_Param3); - Push(a_Param4); - Push(a_Param5); - Push(a_Param6); - Push(a_Param7); - Push(a_Param8); - Push(a_Param9); - if (!CallFunction(5)) - { - return false; - } - GetStackValue(-5, a_Ret1); - GetStackValue(-4, a_Ret2); - GetStackValue(-3, a_Ret3); - GetStackValue(-2, a_Ret4); - GetStackValue(-1, a_Ret5); - lua_pop(m_LuaState, 5); - return true; -} - - - - - diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index 17bae82b3..41b3e3068 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -56,6 +56,7 @@ local Combinations = -- Special combinations: {7, 3}, {8, 3}, + {4, 5}, {9, 5}, } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 31a140c73..0a9d70bcc 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -42,7 +42,6 @@ Implements the 1.7.x protocol classes: #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "Bindings/PluginManager.h" -#include "lua/src/llex.h" -- cgit v1.2.3 From cfdf39a75f68c902e78f78bf3396ce94104903b5 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 16:12:05 +0200 Subject: Added "HOOK_SERVER_PING" call to older protocols --- src/Protocol/ProtocolRecognizer.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index a7fb7bcc2..b197cd384 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -1013,6 +1013,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) { AString Reply; cServer * Server = cRoot::Get()->GetServer(); + + AString Motd = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + switch (cRoot::Get()->GetPrimaryServerVersion()) { case PROTO_VERSION_1_2_5: @@ -1020,11 +1025,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) { // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 Printf(Reply, "%s%s%i%s%i", - Server->GetDescription().c_str(), + Motd.c_str(), cChatColor::Delimiter, - Server->GetNumPlayers(), + NumPlayers, cChatColor::Delimiter, - Server->GetMaxPlayers() + MaxPlayers ); break; } @@ -1051,13 +1056,7 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) m_Buffer.ReadByte(val); // 0x01 magic value ASSERT(val == 0x01); } - - // http://wiki.vg/wiki/index.php?title=Server_List_Ping&oldid=3100 - AString NumPlayers; - Printf(NumPlayers, "%d", Server->GetNumPlayers()); - AString MaxPlayers; - Printf(MaxPlayers, "%d", Server->GetMaxPlayers()); - + AString ProtocolVersionNum; Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion()); AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion())); @@ -1070,11 +1069,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) Reply.push_back(0); Reply.append(ProtocolVersionTxt); Reply.push_back(0); - Reply.append(Server->GetDescription()); + Reply.append(Motd); Reply.push_back(0); - Reply.append(NumPlayers); + Reply.append(Printf("%d", NumPlayers)); Reply.push_back(0); - Reply.append(MaxPlayers); + Reply.append(Printf("%d", MaxPlayers)); break; } } // switch (m_PrimaryServerVersion) -- cgit v1.2.3 From 81979419ad175c98d462ef58cdd39c7c609cd7c5 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 20 Aug 2014 17:56:30 +0200 Subject: RankMgr: Fixed an ignored return value in the API. --- src/Bindings/ManualBindings_RankManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index b109b0097..be8ad12c8 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -83,8 +83,8 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) S.GetStackValues(2, Permission, GroupName); // Add the group to the rank: - cRoot::Get()->GetRankManager().AddPermissionToGroup(Permission, GroupName); - return 0; + S.Push(cRoot::Get()->GetRankManager().AddPermissionToGroup(Permission, GroupName)); + return 1; } -- cgit v1.2.3 From 15a20b1d2aa1229c75bd626af46a0a968aefff96 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 20 Aug 2014 18:09:13 +0200 Subject: RankMgr bindings: fixed GetRankVisuals return value. --- src/Bindings/ManualBindings_RankManager.cpp | 40 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index be8ad12c8..bc31ea687 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -399,11 +399,11 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) -/** Binds cRankManager::GetRankVisuals */ -static int tolua_cRankManager_GetRankVisuals(lua_State * L) +/** Binds cRankManager::GetRankPermissions */ +static int tolua_cRankManager_GetRankPermissions(lua_State * L) { // function signature: - // cRankManager:GetRankVisuals(RankName) -> MsgPrefix, MsgSuffix, MsgNameColorCode + // cRankManager:GetRankPermissions(RankName) -> arraytable of permissions cLuaState S(L); if ( @@ -419,26 +419,23 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) AString RankName; S.GetStackValue(2, RankName); - // Get the visuals: - AString MsgPrefix, MsgSuffix, MsgNameColorCode; - cRoot::Get()->GetRankManager().GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager().GetRankPermissions(RankName); // Push the results: - S.Push(MsgPrefix); - S.Push(MsgSuffix); - S.Push(MsgNameColorCode); - return 3; + S.Push(Permissions); + return 1; } -/** Binds cRankManager::GetRankPermissions */ -static int tolua_cRankManager_GetRankPermissions(lua_State * L) +/** Binds cRankManager::GetRankVisuals */ +static int tolua_cRankManager_GetRankVisuals(lua_State * L) { // function signature: - // cRankManager:GetRankPermissions(RankName) -> arraytable of permissions + // cRankManager:GetRankVisuals(RankName) -> MsgPrefix, MsgSuffix, MsgNameColorCode cLuaState S(L); if ( @@ -454,12 +451,19 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) AString RankName; S.GetStackValue(2, RankName); - // Get the permissions: - AStringVector Permissions = cRoot::Get()->GetRankManager().GetRankPermissions(RankName); + // Get the visuals: + AString MsgPrefix, MsgSuffix, MsgNameColorCode; + if (!cRoot::Get()->GetRankManager().GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode)) + { + // No such rank, return nothing: + return 0; + } // Push the results: - S.Push(Permissions); - return 1; + S.Push(MsgPrefix); + S.Push(MsgSuffix); + S.Push(MsgNameColorCode); + return 3; } @@ -886,8 +890,8 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); - tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); + tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); tolua_function(tolua_S, "GroupExists", tolua_cRankManager_GroupExists); tolua_function(tolua_S, "IsGroupInRank", tolua_cRankManager_IsGroupInRank); tolua_function(tolua_S, "IsPermissionInGroup", tolua_cRankManager_IsPermissionInGroup); -- cgit v1.2.3 From 1b97e4e6ff202f63f5e6ae8a6130536be17b754a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 20 Aug 2014 20:37:51 +0200 Subject: cPlayer: Exported the LoadRank function to Lua API. --- src/Entities/Player.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 0ae014eeb..bfafcb7fb 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -416,13 +416,13 @@ public: /** Returns the UUID (short format) that has been read from the client, or empty string if not available. */ const AString & GetUUID(void) const { return m_UUID; } - // tolua_end - /** (Re)loads the rank and permissions from the cRankManager. Expects the m_UUID member to be valid. Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */ void LoadRank(void); + // tolua_end + // cEntity overrides: virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsSprinting(void) const { return m_IsSprinting; } -- cgit v1.2.3 From cf5ab14ca59904e208bf6cb9d87134f01803eeed Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 22:19:50 +0200 Subject: Added a_ClientHandle to the HOOK_SERVER_PING hook. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 5 +++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Bindings/gen_LuaState_Call.lua | 2 +- src/Protocol/Protocol17x.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.cpp | 3 +++ 8 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index fef86822d..16d789598 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -91,7 +91,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; - virtual bool OnServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; + virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index dbe2e7a0d..343164ec7 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1193,14 +1193,14 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity -bool cPluginLua::OnServerPing(AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginLua::OnServerPing(cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); + m_LuaState.Call((int)(**itr), &a_ClientHandle, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); if (res) { return true; @@ -1590,6 +1590,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_PLUGINS_LOADED: return "OnPluginsLoaded"; case cPluginManager::HOOK_POST_CRAFTING: return "OnPostCrafting"; case cPluginManager::HOOK_PRE_CRAFTING: return "OnPreCrafting"; + case cPluginManager::HOOK_SERVER_PING: return "OnServerPing"; case cPluginManager::HOOK_SPAWNED_ENTITY: return "OnSpawnedEntity"; case cPluginManager::HOOK_SPAWNED_MONSTER: return "OnSpawnedMonster"; case cPluginManager::HOOK_SPAWNING_ENTITY: return "OnSpawningEntity"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 185b2a887..549045849 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -117,7 +117,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; - virtual bool OnServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; + virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index fcbb446c1..2ce46e8fe 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1189,14 +1189,14 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil -bool cPluginManager::CallHookServerPing(AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginManager::CallHookServerPing(cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { FIND_HOOK(HOOK_SERVER_PING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnServerPing(a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) + if ((*itr)->OnServerPing(a_ClientHandle, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index db8a2ca64..ac46fc077 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -226,7 +226,7 @@ public: bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); - bool CallHookServerPing (AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); + bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index 41b3e3068..c1d1af771 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -56,7 +56,7 @@ local Combinations = -- Special combinations: {7, 3}, {8, 3}, - {4, 5}, + {5, 5}, {9, 5}, } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 0a9d70bcc..565532913 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1721,7 +1721,7 @@ void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) int NumPlayers = Server->GetNumPlayers(); int MaxPlayers = Server->GetMaxPlayers(); AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(Motd, NumPlayers, MaxPlayers, Favicon); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon); // Version: Json::Value Version; @@ -3091,7 +3091,7 @@ void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) int NumPlayers = Server->GetNumPlayers(); int MaxPlayers = Server->GetMaxPlayers(); AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(Motd, NumPlayers, MaxPlayers, Favicon); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon); // Version: Json::Value Version; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index b197cd384..af5a8a416 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -18,6 +18,7 @@ #include "../Server.h" #include "../World.h" #include "../ChatColor.h" +#include "Bindings/PluginManager.h" @@ -1017,6 +1018,8 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) AString Motd = Server->GetDescription(); int NumPlayers = Server->GetNumPlayers(); int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon); switch (cRoot::Get()->GetPrimaryServerVersion()) { -- cgit v1.2.3 From 2218f31cde5d04157469de0d5164059ffb8a6bca Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 20 Aug 2014 22:21:41 +0200 Subject: Exported cServer:ShouldAuthenticate to Lua API. --- src/Server.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Server.h b/src/Server.h index c1640b388..f20e6932f 100644 --- a/src/Server.h +++ b/src/Server.h @@ -120,7 +120,7 @@ public: // tolua_export const AString & GetPublicKeyDER(void) const { return m_PublicKeyDER; } /** Returns true if authentication has been turned on in server settings. */ - bool ShouldAuthenticate(void) const { return m_ShouldAuthenticate; } + bool ShouldAuthenticate(void) const { return m_ShouldAuthenticate; } // tolua_export /** Returns true if offline UUIDs should be used to load data for players whose normal UUIDs cannot be found. Loaded from the settings.ini [PlayerData].LoadOfflinePlayerData setting. */ -- cgit v1.2.3 From 4da61e67d7638c46dc56fe451e81a5b4b0f134db Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 20 Aug 2014 22:22:38 +0200 Subject: Renamed a_Motd to a_ServerDescription. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Protocol/Protocol17x.cpp | 6 +++--- src/Protocol/ProtocolRecognizer.cpp | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 16d789598..b4dfeb8cf 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -91,7 +91,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; - virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; + virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 343164ec7..462dda629 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1193,14 +1193,14 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity -bool cPluginLua::OnServerPing(cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginLua::OnServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_ClientHandle, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); + m_LuaState.Call((int)(**itr), &a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 549045849..d3b0d2723 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -117,7 +117,7 @@ public: virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; - virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; + virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 2ce46e8fe..f708c2d85 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1189,14 +1189,14 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil -bool cPluginManager::CallHookServerPing(cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) +bool cPluginManager::CallHookServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) { FIND_HOOK(HOOK_SERVER_PING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnServerPing(a_ClientHandle, a_Motd, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) + if ((*itr)->OnServerPing(a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index ac46fc077..a60a0cdda 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -226,7 +226,7 @@ public: bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); - bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_Motd, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); + bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 565532913..59db0b7d8 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1717,11 +1717,11 @@ void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) { cServer * Server = cRoot::Get()->GetServer(); - AString Motd = Server->GetDescription(); + AString ServerDescription = Server->GetDescription(); int NumPlayers = Server->GetNumPlayers(); int MaxPlayers = Server->GetMaxPlayers(); AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); // Version: Json::Value Version; @@ -1736,7 +1736,7 @@ void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) // Description: Json::Value Description; - Description["text"] = Motd.c_str(); + Description["text"] = ServerDescription.c_str(); // Create the response: Json::Value ResponseValue; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index af5a8a416..6e6cb3caf 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -1015,11 +1015,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) AString Reply; cServer * Server = cRoot::Get()->GetServer(); - AString Motd = Server->GetDescription(); + AString ServerDescription = Server->GetDescription(); int NumPlayers = Server->GetNumPlayers(); int MaxPlayers = Server->GetMaxPlayers(); AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); switch (cRoot::Get()->GetPrimaryServerVersion()) { @@ -1028,7 +1028,7 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) { // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 Printf(Reply, "%s%s%i%s%i", - Motd.c_str(), + ServerDescription.c_str(), cChatColor::Delimiter, NumPlayers, cChatColor::Delimiter, @@ -1072,7 +1072,7 @@ void cProtocolRecognizer::SendLengthlessServerPing(void) Reply.push_back(0); Reply.append(ProtocolVersionTxt); Reply.push_back(0); - Reply.append(Motd); + Reply.append(ServerDescription); Reply.push_back(0); Reply.append(Printf("%d", NumPlayers)); Reply.push_back(0); -- cgit v1.2.3 From 19d1c976e7cd7f6c8a4cb3540d5512a035a4162a Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Thu, 21 Aug 2014 12:08:38 +0200 Subject: Protection Enchantments, some fixes - Protection echantments (fire, blast, feather falling, protection and projectile). It isn't finished, add secondary effects and optimize the code. - Removed some brackets. - Silk touch fixed. --- src/Blocks/BlockHandler.cpp | 15 +++--- src/Entities/ArrowEntity.cpp | 10 ++-- src/Entities/Entity.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++- src/Entities/Player.cpp | 2 +- 4 files changed, 122 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 2238a68a0..0155aa97b 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -428,8 +428,14 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac { if (!a_DropVerbatim) { + ConvertToPickups(Pickups, Meta); + } + else + { + // TODO: Add a proper overridable function for this + // Pickups.Add(m_BlockType, 1, Meta); cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; - if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && (a_Digger->IsPlayer())) + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { switch (m_BlockType) { @@ -459,14 +465,9 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac } else { - ConvertToPickups(Pickups, Meta); + Pickups.Add(m_BlockType, 1, Meta); } } - else - { - // TODO: Add a proper overridable function for this - Pickups.Add(m_BlockType, 1, Meta); - } } // Allow plugins to modify the pickups: diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 12149b297..c3e7c5d79 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -91,7 +91,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (IsOnFire())) + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && IsOnFire()) { m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); m_World->SpawnPrimedTNT(X, Y, Z); @@ -122,12 +122,12 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch); if (PunchLevel > 0) { - Vector3f LookVector = Vector3d(0, 0, 0); + Vector3d LookVector = GetLookVector(); Vector3f FinalSpeed = Vector3f(0, 0, 0); switch (PunchLevel) { - case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); - case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); + case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); break; + case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); break; default: break; } a_EntityHit.SetSpeed(FinalSpeed); @@ -135,7 +135,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if ((IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) + if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming()) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 54e4cf4f5..a4c5c4b2a 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -13,6 +13,7 @@ #include "../Tracer.h" #include "Player.h" #include "Items/ItemHandler.h" +#include "../FastRandom.h" @@ -324,7 +325,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (SharpnessLevel > 0) { - a_TDI.RawDamage += 1.25 * SharpnessLevel; + a_TDI.FinalDamage += 1.25 * SharpnessLevel; } else if (SmiteLevel > 0) { @@ -338,7 +339,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtWither: case cMonster::mtZombiePigman: { - a_TDI.RawDamage += 2.5 * SmiteLevel; + a_TDI.FinalDamage += 2.5 * SmiteLevel; break; } } @@ -404,6 +405,110 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } + if (IsPlayer()){ + double TotalEPF = 0.0; + double EPFProtection = 0.00; + double EPFFireProtection = 0.00; + double EPFBlastProtection = 0.00; + double EPFProjectileProtection = 0.00; + double EPFFeatherFalling = 0.00; + + cEnchantments ChestplateEnchantments = GetEquippedChestplate().m_Enchantments; + cEnchantments LeggingsEnchantments = GetEquippedLeggings().m_Enchantments; + cEnchantments BootsEnchantments = GetEquippedBoots().m_Enchantments; + cEnchantments HelmetEnchantments = GetEquippedHelmet().m_Enchantments; + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProtection) > 0)) + { + EPFProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + + TotalEPF += EPFProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0)) + { + EPFFireProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + + TotalEPF += EPFFireProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0)) + { + EPFFeatherFalling += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + + TotalEPF += EPFFeatherFalling; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0)) + { + EPFBlastProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + + TotalEPF += EPFBlastProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0)) + { + EPFProjectileProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + + TotalEPF += EPFProjectileProtection; + } + + EPFProtection = EPFProtection / TotalEPF; + EPFFireProtection = EPFFireProtection / TotalEPF; + EPFFeatherFalling = EPFFeatherFalling / TotalEPF; + EPFBlastProtection = EPFBlastProtection / TotalEPF; + EPFProjectileProtection = EPFProjectileProtection / TotalEPF; + + if (TotalEPF > 25) TotalEPF = 25; + + cFastRandom Random; + float randomvalue; + randomvalue = Random.GenerateRandomInteger(50, 100) * 0.01; + + TotalEPF = ceil(TotalEPF * randomvalue); + + if (TotalEPF > 20) TotalEPF = 20; + + EPFProtection = TotalEPF * EPFProtection; + EPFFireProtection = TotalEPF * EPFFireProtection; + EPFFeatherFalling = TotalEPF * EPFFeatherFalling; + EPFBlastProtection = TotalEPF * EPFBlastProtection; + EPFProjectileProtection = TotalEPF * EPFProjectileProtection; + + int RemovedDamage = 0; + + if (a_TDI.DamageType != dtInVoid) RemovedDamage += ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + + if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) RemovedDamage += ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtBurning) RemovedDamage += ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtExplosion) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + + a_TDI.FinalDamage -= RemovedDamage; + } m_Health -= (short)a_TDI.FinalDamage; @@ -411,6 +516,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); + if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c1031907d..8b829d090 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1978,7 +1978,7 @@ void cPlayer::UseEquippedItem(int a_Amount) } cFastRandom Random; - if (Random.NextInt(100) <= chance) + if (Random.NextInt(101) <= chance) { return; } -- cgit v1.2.3 From 936604ca95d8e639a6783f9931093b689ce103d9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 15:19:30 +0200 Subject: cMojangAPI: Fixed MakeUUID___() bindings. ToLua would generate a shadow return value for the input strings. --- src/Bindings/ManualBindings.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ src/Protocol/MojangAPI.h | 4 --- 2 files changed, 58 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index a60408910..834f6e073 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2414,6 +2414,62 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) +static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L) +{ + // Function signature: cMojangAPI:MakeUUIDDashed(UUID) -> string + + // Check params: + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cMojangAPI") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString UUID; + S.GetStackValue(2, UUID); + + // Push the result: + S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDDashed(UUID)); + return 1; +} + + + + + +static int tolua_cMojangAPI_MakeUUIDShort(lua_State * L) +{ + // Function signature: cMojangAPI:MakeUUIDShort(UUID) -> string + + // Check params: + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cMojangAPI") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString UUID; + S.GetStackValue(2, UUID); + + // Push the result: + S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDShort(UUID)); + return 1; +} + + + + + static int Lua_ItemGrid_GetSlotCoords(lua_State * L) { tolua_Error tolua_err; @@ -3355,6 +3411,8 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "GetPlayerNameFromUUID", tolua_cMojangAPI_GetPlayerNameFromUUID); tolua_function(tolua_S, "GetUUIDFromPlayerName", tolua_cMojangAPI_GetUUIDFromPlayerName); tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cMojangAPI_GetUUIDsFromPlayerNames); + tolua_function(tolua_S, "MakeUUIDDashed", tolua_cMojangAPI_MakeUUIDDashed); + tolua_function(tolua_S, "MakeUUIDShort", tolua_cMojangAPI_MakeUUIDShort); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cItemGrid"); diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 6ed37625e..e96c0d589 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -38,8 +38,6 @@ public: Returns true if all was successful, false on failure. */ static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response); - // tolua_begin - /** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase). Logs a warning and returns empty string if not a UUID. Note: only checks the string's length, not the actual content. */ @@ -50,8 +48,6 @@ public: Note: only checks the string's length, not the actual content. */ static AString MakeUUIDDashed(const AString & a_UUID); - // tolua_end - /** Converts a player name into a UUID. The UUID will be empty on error. If a_UseOnlyCached is true, the function only consults the cached values. -- cgit v1.2.3 From 8acc8831879582e24c53c18d0442db0b1df6c6b6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 15:29:54 +0200 Subject: Removed cGroup and cGroupManager. --- src/Bindings/AllToLua.pkg | 1 - src/CMakeLists.txt | 4 - src/Entities/Player.cpp | 2 - src/Group.cpp | 41 --------- src/Group.h | 44 --------- src/GroupManager.cpp | 227 ---------------------------------------------- src/GroupManager.h | 36 -------- src/Root.cpp | 16 ---- src/Root.h | 6 -- src/Server.cpp | 26 ++---- 10 files changed, 8 insertions(+), 395 deletions(-) delete mode 100644 src/Group.cpp delete mode 100644 src/Group.h delete mode 100644 src/GroupManager.cpp delete mode 100644 src/GroupManager.h (limited to 'src') diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 88faa9dfc..37e6aecd2 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -67,7 +67,6 @@ $cfile "../Root.h" $cfile "../Cuboid.h" $cfile "../BoundingBox.h" $cfile "../Tracer.h" -$cfile "../Group.h" $cfile "../BlockArea.h" $cfile "../Generating/ChunkDesc.h" $cfile "../CraftingRecipes.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 738b53537..79baf317d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,8 +33,6 @@ SET (SRCS FastRandom.cpp FurnaceRecipe.cpp Globals.cpp - Group.cpp - GroupManager.cpp Inventory.cpp Item.cpp ItemGrid.cpp @@ -98,8 +96,6 @@ SET (HDRS ForEachChunkProvider.h FurnaceRecipe.h Globals.h - Group.h - GroupManager.h Inventory.h Item.h ItemGrid.h diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 423ca3317..b6d6fc7b0 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -10,8 +10,6 @@ #include "../Bindings/PluginManager.h" #include "../BlockEntities/BlockEntity.h" #include "../BlockEntities/EnderChestEntity.h" -#include "../GroupManager.h" -#include "../Group.h" #include "../Root.h" #include "../OSSupport/Timer.h" #include "../Chunk.h" diff --git a/src/Group.cpp b/src/Group.cpp deleted file mode 100644 index def585618..000000000 --- a/src/Group.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Group.h" - - - - - -void cGroup::AddCommand( const AString & a_Command) -{ - m_Commands[ a_Command ] = true; -} - - - - - -void cGroup::AddPermission( const AString & a_Permission) -{ - m_Permissions[ a_Permission ] = true; -} - - - - - -void cGroup::InheritFrom( cGroup* a_Group) -{ - m_Inherits.remove( a_Group); - m_Inherits.push_back( a_Group); -} - - - - - -void cGroup::ClearPermission() -{ - m_Permissions.clear(); -} diff --git a/src/Group.h b/src/Group.h deleted file mode 100644 index 5816f8a06..000000000 --- a/src/Group.h +++ /dev/null @@ -1,44 +0,0 @@ - -#pragma once - - - - - -// tolua_begin -class cGroup -{ -public: - // tolua_end - cGroup() {} - ~cGroup() {} - - // tolua_begin - void SetName( const AString & a_Name) { m_Name = a_Name; } - const AString & GetName() const { return m_Name; } - void SetColor( const AString & a_Color) { m_Color = a_Color; } - void AddCommand( const AString & a_Command); - void AddPermission( const AString & a_Permission); - void InheritFrom( cGroup* a_Group); - // tolua_end - - typedef std::map< AString, bool > PermissionMap; - const PermissionMap & GetPermissions() const { return m_Permissions; } - - void ClearPermission(void); - - typedef std::map< AString, bool > CommandMap; - const CommandMap & GetCommands() const { return m_Commands; } - - const AString & GetColor() const { return m_Color; } // tolua_export - - typedef std::list< cGroup* > GroupList; - const GroupList & GetInherits() const { return m_Inherits; } -private: - AString m_Name; - AString m_Color; - - PermissionMap m_Permissions; - CommandMap m_Commands; - GroupList m_Inherits; -}; // tolua_export diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp deleted file mode 100644 index 4c3dfc6f0..000000000 --- a/src/GroupManager.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "GroupManager.h" -#include "Group.h" -#include "inifile/iniFile.h" -#include "ChatColor.h" -#include "Root.h" - - - - - -typedef std::map< AString, cGroup* > GroupMap; - - - - - -struct cGroupManager::sGroupManagerState -{ - GroupMap Groups; -}; - - - - - -cGroupManager::~cGroupManager() -{ - for (GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr) - { - delete itr->second; - itr->second = NULL; - } - m_pState->Groups.clear(); - - delete m_pState; - m_pState = NULL; -} - - - - - -cGroupManager::cGroupManager() - : m_pState( new sGroupManagerState) -{ - LOGD("-- Loading Groups --"); - - if (!LoadGroups()) - { - LOGWARNING("ERROR: Groups could not load!"); - } - if (!CheckUsers()) - { - LOGWARNING("ERROR: User file could not be found!"); - } - - LOGD("-- Groups Successfully Loaded --"); -} - - - - - -void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile) -{ - LOGWARN("Regenerating users.ini, all users will be reset"); - a_IniFile.AddHeaderComment(" This file stores the players' groups."); - a_IniFile.AddHeaderComment(" The format is:"); - a_IniFile.AddHeaderComment(" [PlayerName]"); - a_IniFile.AddHeaderComment(" Groups = GroupName1, GroupName2, ..."); - - a_IniFile.WriteFile("users.ini"); -} - - - - - -bool cGroupManager::CheckUsers() -{ - cIniFile IniFile; - if (!IniFile.ReadFile("users.ini")) - { - GenerateDefaultUsersIni(IniFile); - return true; - } - - int NumKeys = IniFile.GetNumKeys(); - for (int i = 0; i < NumKeys; i++) - { - AString Player = IniFile.GetKeyName(i); - AString Groups = IniFile.GetValue(Player, "Groups", ""); - if (Groups.empty()) - { - continue; - } - AStringVector Split = StringSplitAndTrim(Groups, ","); - for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) - { - if (!ExistsGroup(*itr)) - { - LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str()); - } - } // for itr - Split[] - } // for i - ini file keys - // Always return true for now, just but we can handle writefile fails later. - return true; -} - - - - - -bool cGroupManager::LoadGroups() -{ - cIniFile IniFile; - if (!IniFile.ReadFile("groups.ini")) - { - LOGWARNING("Regenerating groups.ini, all groups will be reset"); - IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file"); - IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators"); - - IniFile.SetValue("Owner", "Permissions", "*", true); - IniFile.SetValue("Owner", "Color", "2", true); - - IniFile.SetValue("Moderator", "Permissions", "core.time, core.item, core.tpa, core.tpaccept, core.ban, core.unban, core.save-all, core.toggledownfall"); - IniFile.SetValue("Moderator", "Color", "2", true); - IniFile.SetValue("Moderator", "Inherits", "Player", true); - - IniFile.SetValue("Player", "Permissions", "core.portal", true); - IniFile.SetValue("Player", "Color", "f", true); - IniFile.SetValue("Player", "Inherits", "Default", true); - - IniFile.SetValue("Default", "Permissions", "core.help, core.plugins, core.spawn, core.worlds, core.back, core.motd, core.build, core.locate, core.viewdistance", true); - IniFile.SetValue("Default", "Color", "f", true); - - IniFile.WriteFile("groups.ini"); - } - - int NumKeys = IniFile.GetNumKeys(); - for (int i = 0; i < NumKeys; i++) - { - AString KeyName = IniFile.GetKeyName(i); - cGroup * Group = GetGroup(KeyName.c_str()); - - Group->ClearPermission(); // Needed in case the groups are reloaded. - - LOGD("Loading group %s", KeyName.c_str()); - - Group->SetName(KeyName); - AString Color = IniFile.GetValue(KeyName, "Color", "-"); - if ((Color != "-") && (Color.length() >= 1)) - { - Group->SetColor(AString(cChatColor::Delimiter) + Color[0]); - } - else - { - Group->SetColor(cChatColor::White); - } - - AString Commands = IniFile.GetValue(KeyName, "Commands", ""); - if (!Commands.empty()) - { - AStringVector Split = StringSplitAndTrim(Commands, ","); - for (size_t i = 0; i < Split.size(); i++) - { - Group->AddCommand(Split[i]); - } - } - - AString Permissions = IniFile.GetValue(KeyName, "Permissions", ""); - if (!Permissions.empty()) - { - AStringVector Split = StringSplitAndTrim(Permissions, ","); - for (size_t i = 0; i < Split.size(); i++) - { - Group->AddPermission(Split[i]); - } - } - - AString Groups = IniFile.GetValue(KeyName, "Inherits", ""); - if (!Groups.empty()) - { - AStringVector Split = StringSplitAndTrim(Groups, ","); - for (size_t i = 0; i < Split.size(); i++) - { - Group->InheritFrom(GetGroup(Split[i].c_str())); - } - } - } - // Always return true, we can handle writefile fails later. - return true; -} - - - - - -bool cGroupManager::ExistsGroup( const AString & a_Name) -{ - GroupMap::iterator itr = m_pState->Groups.find( a_Name); - return ( itr != m_pState->Groups.end()); -} - - - - - -cGroup* cGroupManager::GetGroup( const AString & a_Name) -{ - GroupMap::iterator itr = m_pState->Groups.find( a_Name); - if (itr != m_pState->Groups.end()) - { - return itr->second; - } - - cGroup* Group = new cGroup(); - m_pState->Groups[a_Name] = Group; - - return Group; -} - - - - diff --git a/src/GroupManager.h b/src/GroupManager.h deleted file mode 100644 index d42b55c4a..000000000 --- a/src/GroupManager.h +++ /dev/null @@ -1,36 +0,0 @@ - -#pragma once - - - - - -class cGroup; - - - - - -class cGroupManager -{ -public: - bool ExistsGroup(const AString & a_Name); - cGroup * GetGroup(const AString & a_Name); - bool LoadGroups(); - bool CheckUsers(); - - /** Writes the default header to the specified ini file, and saves it as "users.ini". */ - static void GenerateDefaultUsersIni(cIniFile & a_IniFile); - -private: - friend class cRoot; - cGroupManager(); - ~cGroupManager(); - - struct sGroupManagerState; - sGroupManagerState * m_pState; -} ; - - - - diff --git a/src/Root.cpp b/src/Root.cpp index 333d92de5..18221781d 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -6,7 +6,6 @@ #include "World.h" #include "WebAdmin.h" #include "FurnaceRecipe.h" -#include "GroupManager.h" #include "CraftingRecipes.h" #include "Bindings/PluginManager.h" #include "MonsterConfig.h" @@ -46,7 +45,6 @@ cRoot::cRoot(void) : m_InputThread(NULL), m_Server(NULL), m_MonsterConfig(NULL), - m_GroupManager(NULL), m_CraftingRecipes(NULL), m_FurnaceRecipe(NULL), m_WebAdmin(NULL), @@ -157,7 +155,6 @@ void cRoot::Start(void) LOGD("Loading settings..."); m_RankManager.Initialize(m_MojangAPI); - m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); @@ -236,8 +233,6 @@ void cRoot::Start(void) LOGD("Unloading recipes..."); delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; delete m_CraftingRecipes; m_CraftingRecipes = NULL; - LOGD("Forgetting groups..."); - delete m_GroupManager; m_GroupManager = NULL; LOGD("Unloading worlds..."); UnloadWorlds(); @@ -546,17 +541,6 @@ void cRoot::SaveAllChunks(void) -void cRoot::ReloadGroups(void) -{ - LOG("Reload groups ..."); - m_GroupManager->LoadGroups(); - m_GroupManager->CheckUsers(); -} - - - - - void cRoot::BroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix) { for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr) diff --git a/src/Root.h b/src/Root.h index 68469c72f..2e870a1ee 100644 --- a/src/Root.h +++ b/src/Root.h @@ -14,7 +14,6 @@ // fwd: class cThread; class cMonsterConfig; -class cGroupManager; class cCraftingRecipes; class cFurnaceRecipe; class cWebAdmin; @@ -79,7 +78,6 @@ public: cMonsterConfig * GetMonsterConfig(void) { return m_MonsterConfig; } - cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export cFurnaceRecipe * GetFurnaceRecipe (void) { return m_FurnaceRecipe; } // Exported in ManualBindings.cpp with quite a different signature @@ -124,9 +122,6 @@ public: /// Saves all chunks in all worlds void SaveAllChunks(void); // tolua_export - /// Reloads all the groups - void ReloadGroups(void); // tolua_export - /// Calls the callback for each player in all worlds bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << @@ -189,7 +184,6 @@ private: cServer * m_Server; cMonsterConfig * m_MonsterConfig; - cGroupManager * m_GroupManager; cCraftingRecipes * m_CraftingRecipes; cFurnaceRecipe * m_FurnaceRecipe; cWebAdmin * m_WebAdmin; diff --git a/src/Server.cpp b/src/Server.cpp index 42ad133f1..012a51883 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -11,7 +11,6 @@ #include "World.h" #include "ChunkDef.h" #include "Bindings/PluginManager.h" -#include "GroupManager.h" #include "ChatColor.h" #include "Entities/Player.h" #include "Inventory.h" @@ -469,25 +468,17 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac PrintHelp(split, a_Output); return; } - if (split[0] == "reload") + else if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); - cRoot::Get()->ReloadGroups(); return; } - if (split[0] == "reloadplugins") + else if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); return; } - if (split[0] == "reloadgroups") - { - cRoot::Get()->ReloadGroups(); - a_Output.Out("Groups reloaded!"); - a_Output.Finished(); - return; - } - if (split[0] == "load") + else if (split[0] == "load") { if (split.size() > 1) { @@ -502,8 +493,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac return; } } - - if (split[0] == "unload") + else if (split[0] == "unload") { if (split.size() > 1) { @@ -519,21 +509,21 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac } // There is currently no way a plugin can do these (and probably won't ever be): - if (split[0].compare("chunkstats") == 0) + else if (split[0].compare("chunkstats") == 0) { cRoot::Get()->LogChunkStats(a_Output); a_Output.Finished(); return; } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) - if (split[0].compare("dumpmem") == 0) + else if (split[0].compare("dumpmem") == 0) { LeakFinderXmlOutput Output("memdump.xml"); DumpUsedMemory(&Output); return; } - if (split[0].compare("killmem") == 0) + else if (split[0].compare("killmem") == 0) { for (;;) { @@ -542,7 +532,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac } #endif - if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output)) + else if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output)) { a_Output.Finished(); return; -- cgit v1.2.3 From b8d3ddb40992699e8d01f74b829b44047fdef048 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 15:49:32 +0200 Subject: Removed Group.h from Bindings' dependencies. --- src/Bindings/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index b87192b47..7a1769e9a 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -97,7 +97,6 @@ set(BINDING_DEPENDENCIES ../Entities/HangingEntity.h ../Entities/ItemFrame.h ../Generating/ChunkDesc.h - ../Group.h ../Inventory.h ../Item.h ../ItemGrid.h -- cgit v1.2.3 From 263ea5464b6761f7442d642006f9b9728b153ec1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 15:53:22 +0200 Subject: Removed last remnant of cGroup. --- src/Entities/Player.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index bfafcb7fb..9821cc6d9 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -13,7 +13,6 @@ -class cGroup; class cWindow; class cClientHandle; class cTeam; -- cgit v1.2.3 From 326dd7e4c6baa6070d35a2a46ca20404c623c8e1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 16:55:39 +0200 Subject: RankMgr: Added cRankManager::RemovePlayerRank(). --- src/Bindings/ManualBindings_RankManager.cpp | 30 +++++++++++++++++++++++++++++ src/RankManager.cpp | 23 ++++++++++++++++++++++ src/RankManager.h | 6 ++++++ 3 files changed, 59 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index bc31ea687..5351c028d 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -717,6 +717,35 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) +/** Binds cRankManager::RemovePlayerRank */ +static int tolua_cRankManager_RemovePlayerRank(lua_State * L) +{ + // function signature: + // cRankManager:RemovePlayerRank(PlayerUUID) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Remove the player's rank: + cRoot::Get()->GetRankManager().RemovePlayerRank(PlayerUUID); + return 0; +} + + + + + /** Binds cRankManager::RemoveRank */ static int tolua_cRankManager_RemoveRank(lua_State * L) { @@ -900,6 +929,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "RemoveGroup", tolua_cRankManager_RemoveGroup); tolua_function(tolua_S, "RemoveGroupFromRank", tolua_cRankManager_RemoveGroupFromRank); tolua_function(tolua_S, "RemovePermissionFromGroup", tolua_cRankManager_RemovePermissionFromGroup); + tolua_function(tolua_S, "RemovePlayerRank", tolua_cRankManager_RemovePlayerRank); tolua_function(tolua_S, "RemoveRank", tolua_cRankManager_RemoveRank); tolua_function(tolua_S, "RenameGroup", tolua_cRankManager_RenameGroup); tolua_function(tolua_S, "RenameRank", tolua_cRankManager_RenameRank); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 96c4baa56..65e5d264c 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -1424,6 +1424,29 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a +void cRankManager::RemovePlayerRank(const AString & a_PlayerUUID) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + SQLite::Statement stmt(m_DB, "DELETE FROM PlayerRank WHERE PlayerUUID = ?"); + stmt.bind(1, a_PlayerUUID); + stmt.exec(); + } + catch(const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove rank from player UUID %s: %s", + __FUNCTION__, a_PlayerUUID.c_str(), ex.what() + ); + } +} + + + + + void cRankManager::SetRankVisuals( const AString & a_RankName, const AString & a_MsgPrefix, diff --git a/src/RankManager.h b/src/RankManager.h index 3ccbd2fd4..532b4cd83 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -155,6 +155,12 @@ public: cPlayer instances manually. The PlayerName is provided for reference, so that GetRankPlayerNames() can work. */ void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName); + + /** Removes the player's rank assignment. The player is left without a rank. + Note that this doesn't change the cPlayer instances for the already connected players, you need to update + all the instances manually. + No action if the player has no rank assigned to them already. */ + void RemovePlayerRank(const AString & a_PlayerUUID); /** Sets the message visuals of an existing rank. No action if the rank name is not found. */ void SetRankVisuals( -- cgit v1.2.3 From 0c04bf962ed025789c1979c6d4fb122735b1a46b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 20:47:52 +0200 Subject: cMojangAPI updates cRankManager's playernames. --- src/Protocol/MojangAPI.cpp | 19 +++++++++++++++++++ src/Protocol/MojangAPI.h | 22 +++++++++++++++++++++- src/RankManager.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/RankManager.h | 9 +++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 823ff5469..3786fecc9 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -10,6 +10,7 @@ #include "inifile/iniFile.h" #include "json/json.h" #include "PolarSSL++/BlockingSslClientSocket.h" +#include "../RankManager.h" @@ -300,6 +301,7 @@ void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const cCSLock Lock(m_CSUUIDToName); m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now); } + NotifyNameUUID(a_PlayerName, a_UUID); } @@ -322,6 +324,7 @@ void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & cCSLock Lock(m_CSUUIDToProfile); m_UUIDToProfile[UUID] = sProfile(a_PlayerName, UUID, a_Properties, Now); } + NotifyNameUUID(a_PlayerName, a_UUID); } @@ -669,6 +672,7 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) continue; } m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now); + NotifyNameUUID(JsonName, JsonUUID); } // for idx - root[] } // cCSLock (m_CSNameToUUID) @@ -792,6 +796,21 @@ void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) cCSLock Lock(m_CSNameToUUID); m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); } + NotifyNameUUID(PlayerName, a_UUID); +} + + + + + +void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID) +{ + // Notify the rank manager: + cCSLock Lock(m_CSRankMgr); + if (m_RankMgr != NULL) + { + m_RankMgr->NotifyNameUUID(a_PlayerName, a_UUID); + } } diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index e96c0d589..252d32543 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -11,6 +11,13 @@ #include + + + + +// fwd: ../RankManager.h" +class cRankManager; + namespace Json { class Value; @@ -81,7 +88,10 @@ public: /** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds the profile to the respective mapping caches and updtes their datetime stamp to now. */ void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties); - + + /** Sets the m_RankMgr that is used for name-uuid notifications. Accepts NULL to remove the binding. */ + void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; } + protected: /** Holds data for a single player profile. */ struct sProfile @@ -161,6 +171,12 @@ protected: /** Protects m_UUIDToProfile against simultaneous multi-threaded access. */ cCriticalSection m_CSUUIDToProfile; + + /** The rank manager that is notified of the name-uuid pairings. May be NULL. Protected by m_CSRankMgr. */ + cRankManager * m_RankMgr; + + /** Protects m_RankMgr agains simultaneous multi-threaded access. */ + cCriticalSection m_CSRankMgr; /** Loads the caches from a disk storage. */ @@ -178,6 +194,10 @@ protected: UUIDs that are not valid will not be added into the cache. ASSUMEs that a_UUID is a lowercased short UUID. */ void CacheUUIDToProfile(const AString & a_UUID); + + /** Called for each name-uuid pairing that is discovered. + If assigned, notifies the m_RankManager of the event. */ + void NotifyNameUUID(const AString & a_PlayerName, const AString & a_PlayerUUID); } ; // tolua_export diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 65e5d264c..349582950 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -365,7 +365,8 @@ protected: cRankManager::cRankManager(void) : m_DB("Ranks.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE), - m_IsInitialized(false) + m_IsInitialized(false), + m_MojangAPI(NULL) { } @@ -373,6 +374,18 @@ cRankManager::cRankManager(void) : +cRankManager::~cRankManager() +{ + if (m_MojangAPI != NULL) + { + m_MojangAPI->SetRankManager(NULL); + } +} + + + + + void cRankManager::Initialize(cMojangAPI & a_MojangAPI) { ASSERT(!m_IsInitialized); // Calling Initialize for the second time? @@ -386,6 +399,8 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) m_IsInitialized = true; + a_MojangAPI.SetRankManager(this); + // Check if tables empty, migrate from ini files then if (AreDBTablesEmpty()) { @@ -1655,6 +1670,28 @@ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AStri +void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET PlayerName = ? WHERE PlayerUUID = ?"); + stmt.bind(1, a_PlayerName); + stmt.bind(2, a_UUID); + stmt.exec(); + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to update DB: %s", __FUNCTION__, ex.what()); + } +} + + + + + bool cRankManager::AreDBTablesEmpty(void) { return ( diff --git a/src/RankManager.h b/src/RankManager.h index 532b4cd83..24030ef22 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -49,6 +49,8 @@ public: /** Creates the rank manager. Needs to be initialized before other use. */ cRankManager(void); + + ~cRankManager(); /** Initializes the rank manager. Performs migration and default-setting if no data is found in the DB. The a_MojangAPI param is used when migrating from old ini files, to look up player UUIDs. */ @@ -194,6 +196,9 @@ public: /** Returns true iff the specified group contains the specified permission. */ bool IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName); + /** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */ + void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID); + protected: /** The database storage for all the data. Protected by m_CS. */ @@ -204,6 +209,10 @@ protected: /** Set to true once the manager is initialized. */ bool m_IsInitialized; + + /** The MojangAPI instance that is used for translating playernames to UUIDs. + Set in Initialize(), may be NULL. */ + cMojangAPI * m_MojangAPI; /** Returns true if all the DB tables are empty, indicating a fresh new install. */ -- cgit v1.2.3 From 1e5d770d7f55c8d6ce7c0afa3bc75d416e6ac935 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 21:37:52 +0200 Subject: Fixed a compile-time warning in MSVC. --- src/Bindings/PluginLua.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index d0b4fa617..ad8528114 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -842,7 +842,7 @@ bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Player, &a_OldPosition, &a_NewPosition, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, a_OldPosition, a_NewPosition, cLuaState::Return, res); if (res) { return true; -- cgit v1.2.3 From c22261252f98e3bb5f0f319c610ad6990b6e199f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 21:38:21 +0200 Subject: Sorted the generated param count. --- src/Bindings/gen_LuaState_Call.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index c1d1af771..13ef8b882 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -54,9 +54,9 @@ local Combinations = {9, 2}, -- Special combinations: + {5, 5}, {7, 3}, {8, 3}, - {5, 5}, {9, 5}, } -- cgit v1.2.3 From d471ee8a9d93d1c793db316b00dcc8eddcdc2c2a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 21:38:57 +0200 Subject: Fixed 1.7.2 login packet reading. Fixes #1317. --- src/Protocol/Protocol17x.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index a8df948cd..1091b877f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1824,7 +1824,11 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) { AString Username; - a_ByteBuffer.ReadVarUTF8String(Username); + if (!a_ByteBuffer.ReadVarUTF8String(Username)) + { + m_Client->Kick("Bad username"); + return; + } if (!m_Client->HandleHandshake(Username)) { -- cgit v1.2.3 From 81d238e0805eb8bd5ae3e844129bd11d62e1e8fd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 21:53:25 +0200 Subject: Added cWorld initializers. --- src/World.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 2027e215a..d7fa7e0d1 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -251,8 +251,38 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin m_TimeOfDay(0), m_LastTimeUpdate(0), m_SkyDarkness(0), + m_GameMode(gmNotSet), + m_bEnabledPVP(false), + m_IsDeepSnowEnabled(false), + m_ShouldLavaSpawnFire(true), + m_VillagersShouldHarvestCrops(true), + m_SimulatorManager(NULL), + m_SandSimulator(NULL), + m_WaterSimulator(NULL), + m_LavaSimulator(NULL), + m_FireSimulator(NULL), + m_RedstoneSimulator(NULL), + m_MaxPlayers(10), + m_ChunkMap(NULL), + m_bAnimals(true), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) + m_MaxCactusHeight(3), + m_MaxSugarcaneHeight(4), + m_IsCactusBonemealable(false), + m_IsCarrotsBonemealable(true), + m_IsCropsBonemealable(true), + m_IsGrassBonemealable(true), + m_IsMelonStemBonemealable(true), + m_IsMelonBonemealable(true), + m_IsPotatoesBonemealable(true), + m_IsPumpkinStemBonemealable(true), + m_IsPumpkinBonemealable(true), + m_IsSaplingBonemealable(true), + m_IsSugarcaneBonemealable(false), + m_bCommandBlocksEnabled(true), + m_bUseChatPrefixes(false), + m_TNTShrapnelLevel(slNone), m_Scoreboard(this), m_MapManager(this), m_GeneratorCallbacks(*this), -- cgit v1.2.3 From 4358421cd46dd8d8275aba964e9a1532c34439d8 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 21:58:08 +0200 Subject: cSetChunkData: Added missing initializers. --- src/SetChunkData.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index 6e0c2733e..af6ad1251 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -13,6 +13,9 @@ cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), + m_IsLightValid(false), + m_IsHeightMapValid(false), + m_AreBiomesValid(false), m_ShouldMarkDirty(a_ShouldMarkDirty) { } -- cgit v1.2.3 From 64fec204c4c5062461a7188b58026d062519b417 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 21 Aug 2014 22:39:53 +0200 Subject: Added initializers for class members. As reported by Coverity, these weren't initialized. --- src/BlockArea.cpp | 4 +++- src/ChunkDef.h | 2 +- src/ClientHandle.cpp | 10 ++++++++++ src/DeadlockDetect.cpp | 4 +++- src/Generating/Caves.cpp | 3 +++ src/Generating/ChunkGenerator.cpp | 1 + src/Generating/HeiGen.cpp | 8 +++++++- src/HTTPServer/HTTPConnection.cpp | 3 ++- src/HTTPServer/HTTPFormParser.cpp | 8 ++++++-- src/LightingThread.cpp | 6 +++++- src/Noise.cpp | 5 +++++ src/PolarSSL++/SslContext.cpp | 1 + src/Server.cpp | 4 +++- src/WorldStorage/FastNBT.h | 4 ++++ 14 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index a0dcb5ec8..90f7ca6c9 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1764,7 +1764,9 @@ NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBL cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : m_Area(a_Area), - m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z) + m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z), + m_CurrentChunkX(0), + m_CurrentChunkZ(0) { } diff --git a/src/ChunkDef.h b/src/ChunkDef.h index dbb782d26..51075ab4a 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -419,7 +419,7 @@ public: X Data; cCoordWithData(int a_X, int a_Y, int a_Z) : - x(a_X), y(a_Y), z(a_Z) + x(a_X), y(a_Y), z(a_Z), Data() { } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e2b438831..ee4fdfa7d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -75,11 +75,21 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_TimeSinceLastPacket(0), m_Ping(1000), m_PingID(1), + m_PingStartTime(0), + m_LastPingTime(1000), m_BlockDigAnimStage(-1), + m_BlockDigAnimSpeed(0), + m_BlockDigAnimX(0), + m_BlockDigAnimY(256), // Invalid Y, so that the coords don't get picked up + m_BlockDigAnimZ(0), m_HasStartedDigging(false), + m_LastDigBlockX(0), + m_LastDigBlockY(256), // Invalid Y, so that the coords don't get picked up + m_LastDigBlockZ(0), m_State(csConnected), m_ShouldCheckDownloaded(false), m_NumExplosionsThisTick(0), + m_NumBlockChangeInteractionsThisTick(0), m_UniqueID(0), m_HasSentPlayerChunk(false), m_Locale("en_GB") diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index f73a45555..7f703416c 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -21,7 +21,8 @@ const int CYCLE_MILLISECONDS = 100; cDeadlockDetect::cDeadlockDetect(void) : - super("DeadlockDetect") + super("DeadlockDetect"), + m_IntervalSec(1000) { } @@ -136,6 +137,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age) void cDeadlockDetect::DeadlockDetected(void) { + LOGERROR("Deadlock detected, aborting the server"); ASSERT(!"Deadlock detected"); abort(); } diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 6fc371958..71154dff9 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -166,6 +166,9 @@ cCaveTunnel::cCaveTunnel( if ((a_BlockStartY <= 0) && (a_BlockEndY <= 0)) { // Don't bother detailing this cave, it's under the world anyway + m_MinBlockX = m_MaxBlockX = 0; + m_MinBlockY = m_MaxBlockY = -1; + m_MinBlockZ = m_MaxBlockZ = 0; return; } diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 3d5af152c..a1188f984 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -27,6 +27,7 @@ const unsigned int QUEUE_SKIP_LIMIT = 500; cChunkGenerator::cChunkGenerator(void) : super("cChunkGenerator"), + m_Seed(0), // Will be overwritten by the actual generator m_Generator(NULL), m_PluginInterface(NULL), m_ChunkSink(NULL) diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index c3f3b38a9..79d529a6a 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -239,7 +239,13 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel cHeiGenClassic::cHeiGenClassic(int a_Seed) : m_Seed(a_Seed), - m_Noise(a_Seed) + m_Noise(a_Seed), + m_HeightFreq1(1.0f), + m_HeightAmp1(1.0f), + m_HeightFreq2(0.5f), + m_HeightAmp2(0.5f), + m_HeightFreq3(0.1f), + m_HeightAmp3(0.1f) { } diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index b9c762e7c..bf46bb241 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -15,7 +15,8 @@ cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) : m_HTTPServer(a_HTTPServer), m_State(wcsRecvHeaders), - m_CurrentRequest(NULL) + m_CurrentRequest(NULL), + m_CurrentRequestBodyRemaining(0) { // LOGD("HTTP: New connection at %p", this); } diff --git a/src/HTTPServer/HTTPFormParser.cpp b/src/HTTPServer/HTTPFormParser.cpp index 9ddfb82f1..c50c6dcf2 100644 --- a/src/HTTPServer/HTTPFormParser.cpp +++ b/src/HTTPServer/HTTPFormParser.cpp @@ -15,7 +15,9 @@ cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callbacks) : m_Callbacks(a_Callbacks), - m_IsValid(true) + m_IsValid(true), + m_IsCurrentPartFile(false), + m_FileHasBeenAnnounced(false) { if (a_Request.GetMethod() == "GET") { @@ -55,7 +57,9 @@ cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callba cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks) : m_Callbacks(a_Callbacks), m_Kind(a_Kind), - m_IsValid(true) + m_IsValid(true), + m_IsCurrentPartFile(false), + m_FileHasBeenAnnounced(false) { Parse(a_Data, a_Size); } diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 3fbbee6b5..652b03e46 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -73,6 +73,8 @@ public: HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) : + m_ReadingChunkX(0), + m_ReadingChunkZ(0), m_MaxHeight(0), m_BlockTypes(a_BlockTypes), m_HeightMap(a_HeightMap) @@ -89,7 +91,9 @@ public: cLightingThread::cLightingThread(void) : super("cLightingThread"), - m_World(NULL) + m_World(NULL), + m_MaxHeight(0), + m_NumSeeds(0) { } diff --git a/src/Noise.cpp b/src/Noise.cpp index 507d05ea5..71e801f30 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -146,6 +146,8 @@ cCubicCell2D::cCubicCell2D( ) : m_Noise(a_Noise), m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), m_Array(a_Array), m_SizeX(a_SizeX), m_SizeY(a_SizeY), @@ -300,6 +302,9 @@ cCubicCell3D::cCubicCell3D( ) : m_Noise(a_Noise), m_WorkRnds(&m_Workspace1), + m_CurFloorX(0), + m_CurFloorY(0), + m_CurFloorZ(0), m_Array(a_Array), m_SizeX(a_SizeX), m_SizeY(a_SizeY), diff --git a/src/PolarSSL++/SslContext.cpp b/src/PolarSSL++/SslContext.cpp index c3074f197..482470c3a 100644 --- a/src/PolarSSL++/SslContext.cpp +++ b/src/PolarSSL++/SslContext.cpp @@ -16,6 +16,7 @@ cSslContext::cSslContext(void) : m_IsValid(false), m_HasHandshaken(false) { + memset(&m_Ssl, 0, sizeof(m_Ssl)); } diff --git a/src/Server.cpp b/src/Server.cpp index 42ad133f1..cbb9fba4d 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -117,7 +117,9 @@ cServer::cServer(void) : m_MaxPlayers(0), m_bIsHardcore(false), m_TickThread(*this), - m_ShouldAuthenticate(false) + m_ShouldAuthenticate(false), + m_ShouldLoadOfflinePlayerData(false), + m_ShouldLoadNamedPlayerData(true) { } diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index 4ef72e379..ebf99103f 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -76,7 +76,9 @@ public: cFastNBTTag(eTagType a_Type, int a_Parent) : m_Type(a_Type), + m_NameStart(0), m_NameLength(0), + m_DataStart(0), m_DataLength(0), m_Parent(a_Parent), m_PrevSibling(-1), @@ -88,7 +90,9 @@ public: cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) : m_Type(a_Type), + m_NameStart(0), m_NameLength(0), + m_DataStart(0), m_DataLength(0), m_Parent(a_Parent), m_PrevSibling(a_PrevSibling), -- cgit v1.2.3 From 51df169ad58f4712312d0400043cf2094fc9dfd6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 22 Aug 2014 10:33:15 +0200 Subject: cLuaState: Fixed Vector3<> names pushed to Lua. --- src/Bindings/LuaState.cpp | 46 +++++++++++++++++++++++++++++++++++++++++----- src/Bindings/LuaState.h | 3 +++ 2 files changed, 44 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index e123a87c9..9fe93ccc2 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -460,7 +460,43 @@ void cLuaState::Push(const Vector3d & a_Vector) { ASSERT(IsValid()); - tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3d"); + tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::Push(const Vector3d * a_Vector) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::Push(const Vector3i & a_Vector) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::Push(const Vector3i * a_Vector) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3"); m_NumCurrentFunctionArgs += 1; } @@ -708,11 +744,11 @@ void cLuaState::Push(TakeDamageInfo * a_TDI) -void cLuaState::Push(Vector3i * a_Vector) +void cLuaState::Push(Vector3d * a_Vector) { ASSERT(IsValid()); - tolua_pushusertype(m_LuaState, a_Vector, "Vector3i"); + tolua_pushusertype(m_LuaState, a_Vector, "Vector3"); m_NumCurrentFunctionArgs += 1; } @@ -720,11 +756,11 @@ void cLuaState::Push(Vector3i * a_Vector) -void cLuaState::Push(Vector3d * a_Vector) +void cLuaState::Push(Vector3i * a_Vector) { ASSERT(IsValid()); - tolua_pushusertype(m_LuaState, a_Vector, "Vector3d"); + tolua_pushusertype(m_LuaState, a_Vector, "Vector3"); m_NumCurrentFunctionArgs += 1; } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index afac77ce8..eeb93fd4d 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -186,6 +186,9 @@ public: void Push(const HTTPRequest * a_Request); void Push(const HTTPTemplateRequest * a_Request); void Push(const Vector3d & a_Vector); + void Push(const Vector3d * a_Vector); + void Push(const Vector3i & a_Vector); + void Push(const Vector3i * a_Vector); // Push a value onto the stack (keep alpha-sorted): void Push(bool a_Value); -- cgit v1.2.3 From 2dfcd678c41f0066ff69ea39d9dc4bdbfe8ab621 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 22 Aug 2014 10:33:53 +0200 Subject: Fixed cPlugin::OnPlayerMoving signature. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 2 +- src/Bindings/PluginLua.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 53d4be29d..c9a53346d 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -73,7 +73,7 @@ public: virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; - virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) = 0; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index ad8528114..2c2d05547 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -835,7 +835,7 @@ bool cPluginLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_Block -bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) +bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) { cCSLock Lock(m_CriticalSection); bool res = false; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 2b7358043..eda65b76c 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -98,8 +98,8 @@ public: virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override; - virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; -- cgit v1.2.3 From d2d63b8a055409d0d07c57fd69b27469fe1681ac Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 22 Aug 2014 10:35:51 +0200 Subject: World: Report chunk count for the spawn area. --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index d7fa7e0d1..69d1217f1 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -437,7 +437,7 @@ void cWorld::InitializeSpawn(void) int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist); IniFile.WriteFile(m_IniFileName); - LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str()); + LOG("Preparing spawn area in world \"%s\", %d x %d chunks, total %d chunks...", m_WorldName.c_str(), ViewDist, ViewDist, ViewDist * ViewDist); for (int x = 0; x < ViewDist; x++) { for (int z = 0; z < ViewDist; z++) -- cgit v1.2.3 From 33b595253209cefcf2bda42ab227b84fad6c600f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 22 Aug 2014 11:12:44 +0200 Subject: Fixed a warning in FastRandom. --- src/FastRandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/FastRandom.h b/src/FastRandom.h index 2061a3958..cebebad96 100644 --- a/src/FastRandom.h +++ b/src/FastRandom.h @@ -45,7 +45,7 @@ public: float NextFloat(float a_Range, int a_Salt); /** Returns a random float between 0 and 1. */ - float NextFloat(void) { return NextFloat(1); }; + float NextFloat(void) { return NextFloat(1); } /** Returns a random int in the range [a_Begin .. a_End] */ int GenerateRandomInteger(int a_Begin, int a_End); -- cgit v1.2.3 From 7d771953c0e8275311ca13802e52ccf92a170644 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Fri, 22 Aug 2014 11:49:49 +0200 Subject: More Enchantments - Added Thorns and Respiration enchantments --- src/Blocks/BlockHandler.cpp | 1 - src/Entities/Entity.cpp | 127 ++++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 0155aa97b..c8a57906f 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -433,7 +433,6 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac else { // TODO: Add a proper overridable function for this - // Pickups.Add(m_BlockType, 1, Meta); cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index a4c5c4b2a..760401cc2 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -357,8 +357,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtSilverfish: { a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + // TODO: Add slowness effect + break; - } + }; + default: break; } } } @@ -390,8 +393,27 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) default: StartBurning(BurnTicks * 20); } } + } - + int ThornsLevel = 0; + cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) + { + cItem Item = ArmorItems[i]; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchThorns) > ThornsLevel) ThornsLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchThorns); + } + + if (ThornsLevel > 0) + { + int Chance = ThornsLevel * 15; + + cFastRandom Random; + int RandomValue = Random.GenerateRandomInteger(0, 100); + + if (RandomValue <= Chance) + { + a_TDI.Attacker->TakeDamage(dtAttack, this, 0, Random.GenerateRandomInteger(1, 4), 0); + } } if (!Player->IsOnGround()) @@ -405,6 +427,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } + if (IsPlayer()){ double TotalEPF = 0.0; double EPFProtection = 0.00; @@ -413,65 +436,39 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - cEnchantments ChestplateEnchantments = GetEquippedChestplate().m_Enchantments; - cEnchantments LeggingsEnchantments = GetEquippedLeggings().m_Enchantments; - cEnchantments BootsEnchantments = GetEquippedBoots().m_Enchantments; - cEnchantments HelmetEnchantments = GetEquippedHelmet().m_Enchantments; - - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProtection) > 0)) + cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - EPFProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - - TotalEPF += EPFProtection; - } + cItem Item = ArmorItems[i]; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchProtection) > 0) + { + EPFProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0)) - { - EPFFireProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - - TotalEPF += EPFFireProtection; - } + if (Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + { + EPFFireProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0)) - { - EPFFeatherFalling += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + { + EPFFeatherFalling += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + } - TotalEPF += EPFFeatherFalling; - } + if (Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + { + EPFBlastProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0)) - { - EPFBlastProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + { + EPFProjectileProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + } - TotalEPF += EPFBlastProtection; } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0)) - { - EPFProjectileProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - - TotalEPF += EPFProjectileProtection; - } + TotalEPF = EPFProtection + EPFFireProtection + EPFFeatherFalling + EPFBlastProtection + EPFProjectileProtection; + EPFProtection = EPFProtection / TotalEPF; EPFFireProtection = EPFFireProtection / TotalEPF; @@ -482,10 +479,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (TotalEPF > 25) TotalEPF = 25; cFastRandom Random; - float randomvalue; - randomvalue = Random.GenerateRandomInteger(50, 100) * 0.01; + float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01; - TotalEPF = ceil(TotalEPF * randomvalue); + TotalEPF = ceil(TotalEPF * RandomValue); if (TotalEPF > 20) TotalEPF = 20; @@ -507,9 +503,13 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.FinalDamage < RemovedDamage) RemovedDamage = 0; + a_TDI.FinalDamage -= RemovedDamage; } + + m_Health -= (short)a_TDI.FinalDamage; // TODO: Apply damage to armor @@ -533,7 +533,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case 2: AdditionalSpeed.Set(8, 0.3, 8); break; default: break; } - SetSpeed(a_TDI.Knockback + AdditionalSpeed); + AddSpeed(a_TDI.Knockback + AdditionalSpeed); } m_World->BroadcastEntityStatus(*this, esGenericHurt); @@ -1435,6 +1435,8 @@ void cEntity::HandleAir(void) // See if the entity is /submerged/ water (block above is water) // Get the type of block the entity is standing in: + int RespirationLevel = GetEquippedHelmet().m_Enchantments.GetLevel(cEnchantments::enchRespiration); + if (IsSubmerged()) { if (!IsPlayer()) // Players control themselves @@ -1442,6 +1444,11 @@ void cEntity::HandleAir(void) SetSpeedY(1); // Float in the water } + if (RespirationLevel > 0) + { + ((cPawn *)this)->AddEntityEffect(cEntityEffect::effNightVision, 200, 5, 0); + } + if (m_AirLevel <= 0) { // Runs the air tick timer to check whether the player should be damaged @@ -1468,6 +1475,12 @@ void cEntity::HandleAir(void) // Set the air back to maximum m_AirLevel = MAX_AIR_LEVEL; m_AirTickTimer = DROWNING_TICKS; + + if (RespirationLevel > 0) + { + m_AirTickTimer = DROWNING_TICKS + (RespirationLevel * 15 * 20); + } + } } -- cgit v1.2.3 From 8fa4ac9ad957d951cf25c668ffbb4e5d2fafa7f7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 22 Aug 2014 15:32:27 +0200 Subject: Fixed item drop. Fixes #1341 --- src/ClientHandle.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ee4fdfa7d..8aa883144 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -922,11 +922,16 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB return; } - // Check for clickthrough-blocks: - /* When the user breaks a fire block, the client send the wrong block location. - We must find the right block with the face direction. */ - if (a_BlockFace != BLOCK_FACE_NONE) + if ((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) { + if (a_BlockFace == BLOCK_FACE_NONE) + { + return; + } + + /* Check for clickthrough-blocks: + When the user breaks a fire block, the client send the wrong block location. + We must find the right block with the face direction. */ int BlockX = a_BlockX; int BlockY = a_BlockY; int BlockZ = a_BlockZ; @@ -937,17 +942,16 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB a_BlockY = BlockY; a_BlockZ = BlockZ; } - } - if ( - ((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) && // Only do a radius check for block destruction - things like pickup tossing send coordinates that are to be ignored - ((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || - (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || - (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)) - ) - { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - return; + if ( + ((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)) + ) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } } cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); -- cgit v1.2.3 From 0daacd14d9ab678c08c45a1a1562d5ec160a3ff3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 23 Aug 2014 03:44:04 +0200 Subject: RankMgr: Implemented default rank, added defaults. --- src/RankManager.cpp | 200 ++++++++++++++++++++++++++++++++++++++++++++++------ src/RankManager.h | 22 +++++- 2 files changed, 198 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 349582950..0cee7724b 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -7,6 +7,7 @@ #include "RankManager.h" #include "inifile/iniFile.h" #include "Protocol/MojangAPI.h" +#include "ClientHandle.h" @@ -54,6 +55,9 @@ public: LOGD("Setting ranks..."); SetRanks(); + + LOGD("Creating defaults..."); + CreateDefaults(); return true; } @@ -87,8 +91,11 @@ protected: AString m_Name; AStringVector m_Groups; - /** Assigned by ResolveUserUUIDs() */ + /** Assigned by ResolveUserUUIDs(), contains the online (Mojang) UUID of the player. */ AString m_UUID; + + /** Assigned by ResolveUserUUIDs(), contains the offline (generated) UUID of the player. */ + AString m_OfflineUUID; sUser(void) {} @@ -275,22 +282,15 @@ protected: m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames); // Assign the UUIDs back to players, remove those not resolved: - for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ) + for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ++itr) { AString UUID = m_MojangAPI.GetUUIDFromPlayerName(itr->second.m_Name); if (UUID.empty()) { - LOGWARNING("RankMigrator: Cannot resolve player %s to UUID, player will be left unranked", itr->second.m_Name.c_str()); - sUserMap::iterator itr2 = itr; - ++itr2; - m_Users.erase(itr); - itr = itr2; - } - else - { - itr->second.m_UUID = UUID; - ++itr; + LOGWARNING("RankMigrator: Cannot resolve player %s to online UUID, player will be left unranked in online mode", itr->second.m_Name.c_str()); } + itr->second.m_UUID = UUID; + itr->second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(itr->second.m_Name); } } @@ -350,10 +350,28 @@ protected: AddGroupsToRank(Groups, RankName); } - // Set the rank to the user: - m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName); + // Set the rank to the user, using both the online and offline UUIDs: + m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName); + m_RankManager.SetPlayerRank(itr->second.m_OfflineUUID, itr->second.m_Name, RankName); } // for itr - m_Users[] } + + + + /** Creates the Default rank that contains the Default group, if it exists. + Sets the RankManager's default rank. */ + void CreateDefaults(void) + { + if (!m_RankManager.RankExists("Default")) + { + m_RankManager.AddRank("Default", "", "", ""); + if (!m_RankManager.IsGroupInRank("Default", "Default")) + { + m_RankManager.AddGroupToRank("Default", "Default"); + } + } + m_RankManager.SetDefaultRank("Default"); + } }; @@ -396,6 +414,7 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) m_DB.exec("CREATE TABLE IF NOT EXISTS PermGroup (PermGroupID INTEGER PRIMARY KEY, Name)"); m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermGroup (RankID INTEGER, PermGroupID INTEGER)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (PermGroupID INTEGER, Permission)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS DefaultRank (RankID INTEGER)"); m_IsInitialized = true; @@ -410,12 +429,39 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) if (Migrator.Migrate()) { LOGINFO("Ranks migrated."); + // The default rank has been set by the migrator return; } + + // Migration failed. Add some defaults + LOGINFO("Rank migration failed, creating default ranks..."); + CreateDefaults(); + LOGINFO("Default ranks created."); } - // Migration failed. - // TODO: Check if tables empty, add some defaults then + // Load the default rank: + try + { + SQLite::Statement stmt(m_DB, + "SELECT Rank.Name FROM Rank " + "LEFT JOIN DefaultRank ON Rank.RankID = DefaultRank.RankID" + ); + if (stmt.executeStep()) + { + m_DefaultRank = stmt.getColumn(0).getText(); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Cannot load default rank: %s", __FUNCTION__, ex.what()); + return; + } + + // If the default rank cannot be loaded, use the first rank: + if (m_DefaultRank.empty()) + { + SetDefaultRank(GetAllRanks()[0]); + } } @@ -1085,6 +1131,13 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); + + // Check if the default rank is being removed with a proper replacement: + if ((a_RankName == m_DefaultRank) && !RankExists(a_ReplacementRankName)) + { + LOGWARNING("%s: Cannot remove rank %s, it is the default rank and the replacement rank doesn't exist.", __FUNCTION__, a_RankName.c_str()); + return; + } AStringVector res; try @@ -1143,6 +1196,12 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl stmt.bind(1, RemoveRankID); stmt.exec(); } + + // Update the default rank, if it was the one being removed: + if (a_RankName == m_DefaultRank) + { + m_DefaultRank = a_RankName; + } } catch (const SQLite::Exception & ex) { @@ -1310,21 +1369,30 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa stmt.bind(1, a_NewName); if (stmt.executeStep()) { - LOGD("%s: Rank %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str()); + LOGINFO("%s: Rank %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str()); return false; } } // Rename: - bool res; { SQLite::Statement stmt(m_DB, "UPDATE Rank SET Name = ? WHERE Name = ?"); stmt.bind(1, a_NewName); stmt.bind(2, a_OldName); - res = (stmt.exec() > 0); + if (stmt.exec() <= 0) + { + LOGINFO("%s: There is no rank %s, cannot rename to %s.", __FUNCTION__, a_OldName.c_str(), a_NewName.c_str()); + return false; + } } - return res; + // Update the default rank, if it was the one being renamed: + if (a_OldName == m_DefaultRank) + { + m_DefaultRank = a_NewName; + } + + return true; } catch (const SQLite::Exception & ex) { @@ -1692,6 +1760,57 @@ void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString & +bool cRankManager::SetDefaultRank(const AString & a_RankName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + // Find the rank's ID: + int RankID = 0; + { + SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?"); + stmt.bind(1, a_RankName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Cannot set rank %s as the default, it does not exist.", __FUNCTION__, a_RankName.c_str()); + return false; + } + } + + // Set the rank as the default: + { + SQLite::Statement stmt(m_DB, "UPDATE DefaultRank SET RankID = ?"); + stmt.bind(1, RankID); + if (stmt.exec() < 1) + { + // Failed to update, there might be none in the DB, try inserting: + SQLite::Statement stmt2(m_DB, "INSERT INTO DefaultRank (RankID) VALUES (?)"); + stmt2.bind(1, RankID); + if (stmt2.exec() < 1) + { + LOGINFO("%s: Cannot update the default rank in the DB to %s.", __FUNCTION__, a_RankName.c_str()); + return false; + } + } + } + + // Set the internal cache: + m_DefaultRank = a_RankName; + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to update DB: %s", __FUNCTION__, ex.what()); + return false; + } +} + + + + + bool cRankManager::AreDBTablesEmpty(void) { return ( @@ -1699,7 +1818,8 @@ bool cRankManager::AreDBTablesEmpty(void) IsDBTableEmpty("PlayerRank") && IsDBTableEmpty("PermGroup") && IsDBTableEmpty("RankPermGroup") && - IsDBTableEmpty("PermissionItem") + IsDBTableEmpty("PermissionItem") && + IsDBTableEmpty("DefaultRank") ); } @@ -1724,3 +1844,41 @@ bool cRankManager::IsDBTableEmpty(const AString & a_TableName) + +void cRankManager::CreateDefaults(void) +{ + // Wrap everything in a big transaction to speed things up: + cMassChangeLock Lock(*this); + + // Create ranks: + AddRank("Default", "", "", ""); + AddRank("VIP", "", "", ""); + AddRank("Operator", "", "", ""); + AddRank("Admin", "", "", ""); + + // Create groups: + AddGroup("Default"); + AddGroup("Kick"); + AddGroup("Teleport"); + AddGroup("Everything"); + + // Add groups to ranks: + AddGroupToRank("Default", "Default"); + AddGroupToRank("Teleport", "VIP"); + AddGroupToRank("Teleport", "Operator"); + AddGroupToRank("Kick", "Operator"); + AddGroupToRank("Everything", "Admin"); + + // Add permissions to groups: + AddPermissionToGroup("core.build", "Default"); + AddPermissionToGroup("core.tp", "Teleport"); + AddPermissionToGroup("core.kick", "Kick"); + AddPermissionToGroup("*", "Everything"); + + // Set the default rank: + SetDefaultRank("Default"); +} + + + + diff --git a/src/RankManager.h b/src/RankManager.h index 24030ef22..b93a1157d 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -127,7 +127,9 @@ public: /** Removes the specified rank. All players assigned to that rank will be re-assigned to a_ReplacementRankName. If a_ReplacementRankName is empty or not a valid rank, the player will be removed from the DB, - which means they will receive the default rank the next time they are queried. */ + which means they will receive the default rank the next time they are queried. + If the rank being removed is the default rank, the default will be changed to the replacement + rank; the operation fails if there's no replacement. */ void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); /** Removes the specified group completely. @@ -143,6 +145,7 @@ public: /** Renames the specified rank. No action if the rank name is not found. Fails if the new name is already used. + Updates the cached m_DefaultRank if the default rank is being renamed. Returns true on success, false on failure. */ bool RenameRank(const AString & a_OldName, const AString & a_NewName); @@ -198,13 +201,23 @@ public: /** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */ void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID); - + + /** Sets the specified rank as the default rank. + Returns true on success, false on failure (rank not found). */ + bool SetDefaultRank(const AString & a_RankName); + + /** Returns the name of the default rank. */ + const AString & GetDefaultRank(void) const { return m_DefaultRank; } + protected: /** The database storage for all the data. Protected by m_CS. */ SQLite::Database m_DB; - /** The mutex protecting m_DB against multi-threaded access. */ + /** The name of the default rank. Kept as a cache so that queries for it don't need to go through the DB. */ + AString m_DefaultRank; + + /** The mutex protecting m_DB and m_DefaultRank against multi-threaded access. */ cCriticalSection m_CS; /** Set to true once the manager is initialized. */ @@ -221,6 +234,9 @@ protected: /** Returns true iff the specified DB table is empty. If there's an error while querying, returns false. */ bool IsDBTableEmpty(const AString & a_TableName); + + /** Creates a default set of ranks / groups / permissions. */ + void CreateDefaults(void); } ; -- cgit v1.2.3 From d07134e6212ea39f0d23c7edcfb22573d5b58b77 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 23 Aug 2014 16:06:34 +0100 Subject: Assume POWER is big-endian, so it compiles. [reference](http://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros#POWER) We may want to come back and figure out if the processor is running in little-endian mode, but for now assume they're big-endian. --- src/ByteBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 64b31c60b..96556bf61 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -27,7 +27,7 @@ ) #define IS_LITTLE_ENDIAN #elif ( \ - defined (__ARMEB__) || defined(__sparc) \ + defined (__ARMEB__) || defined(__sparc) || defined(__powerpc__) || defined(__POWERPC__) \ ) #define IS_BIG_ENDIAN #else -- cgit v1.2.3 From da67dd39ed965f134e480fe11cdf140fbd9a9df2 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 23 Aug 2014 17:56:23 +0200 Subject: RankMgr: Unified function signature comments in the bindings. --- src/Bindings/ManualBindings.h | 1 - src/Bindings/ManualBindings_RankManager.cpp | 63 ++++++++++++++++------------- 2 files changed, 36 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index 0302b9503..1b6e65654 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -6,7 +6,6 @@ struct lua_State; - /** Provides namespace for the bindings. */ class ManualBindings { diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 5351c028d..f25f87e46 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -16,6 +16,9 @@ /** Binds cRankManager::AddGroup */ static int tolua_cRankManager_AddGroup(lua_State * L) { + // Function signature: + // cRankManager:AddGroup(GroupName) + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -39,9 +42,12 @@ static int tolua_cRankManager_AddGroup(lua_State * L) -/** Binds cRankManager::AddGroup */ +/** Binds cRankManager::AddGroupToRank */ static int tolua_cRankManager_AddGroupToRank(lua_State * L) { + // Function signature: + // cRankManager:AddGroupToRank(GroupName, RankName) -> bool + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -68,6 +74,9 @@ static int tolua_cRankManager_AddGroupToRank(lua_State * L) /** Binds cRankManager::AddPermissionToGroup */ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) { + // Function signature: + // cRankManager:AddPermissionToGroup(Permission, GroupName) -> bool + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -94,7 +103,7 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) /** Binds cRankManager::AddRank */ static int tolua_cRankManager_AddRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:AddRank(RankName) cLuaState S(L); @@ -123,7 +132,7 @@ static int tolua_cRankManager_AddRank(lua_State * L) /** Binds cRankManager::GetAllGroups */ static int tolua_cRankManager_GetAllGroups(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetAllGroups() -> arraytable of GroupNames cLuaState S(L); @@ -150,7 +159,7 @@ static int tolua_cRankManager_GetAllGroups(lua_State * L) /** Binds cRankManager::GetAllPermissions */ static int tolua_cRankManager_GetAllPermissions(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetAllPermissions() -> arraytable of Permissions cLuaState S(L); @@ -177,7 +186,7 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) /** Binds cRankManager::GetAllRanks */ static int tolua_cRankManager_GetAllRanks(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetAllRanks() -> arraytable of RankNames cLuaState S(L); @@ -204,7 +213,7 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L) /** Binds cRankManager::GetGroupPermissions */ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetGroupPermissions(GroupName) -> arraytable of permissions cLuaState S(L); @@ -236,7 +245,7 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) /** Binds cRankManager::GetPlayerGroups */ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetPlayerGroups(PlayerUUID) -> arraytable of GroupNames cLuaState S(L); @@ -268,7 +277,7 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) /** Binds cRankManager::GetPlayerMsgVisuals */ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetPlayerMsgVisuals(PlayerUUID) -> string, string, string cLuaState S(L); @@ -306,7 +315,7 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) /** Binds cRankManager::GetPlayerPermissions */ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetPlayerPermissions(PlayerUUID) -> arraytable of permissions cLuaState S(L); @@ -338,7 +347,7 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) /** Binds cRankManager::GetPlayerRankName */ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetPlayerRankName(PlayerUUID) -> string cLuaState S(L); @@ -370,7 +379,7 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) /** Binds cRankManager::GetRankGroups */ static int tolua_cRankManager_GetRankGroups(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetRankGroups(RankName) -> arraytable of groupnames cLuaState S(L); @@ -402,7 +411,7 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) /** Binds cRankManager::GetRankPermissions */ static int tolua_cRankManager_GetRankPermissions(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetRankPermissions(RankName) -> arraytable of permissions cLuaState S(L); @@ -434,7 +443,7 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) /** Binds cRankManager::GetRankVisuals */ static int tolua_cRankManager_GetRankVisuals(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GetRankVisuals(RankName) -> MsgPrefix, MsgSuffix, MsgNameColorCode cLuaState S(L); @@ -473,7 +482,7 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) /** Binds cRankManager::GroupExists */ static int tolua_cRankManager_GroupExists(lua_State * L) { - // function signature: + // Function signature: // cRankManager:GroupExists(GroupName) -> bool cLuaState S(L); @@ -505,7 +514,7 @@ static int tolua_cRankManager_GroupExists(lua_State * L) /** Binds cRankManager::IsGroupInRank */ static int tolua_cRankManager_IsGroupInRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:IsGroupInRank(GroupName, RankName) -> bool cLuaState S(L); @@ -537,7 +546,7 @@ static int tolua_cRankManager_IsGroupInRank(lua_State * L) /** Binds cRankManager::IsPermissionInGroup */ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) { - // function signature: + // Function signature: // cRankManager:IsPermissionInGroup(Permission, GroupName) -> bool cLuaState S(L); @@ -569,7 +578,7 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) /** Binds cRankManager::IsPlayerRankSet */ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) { - // function signature: + // Function signature: // cRankManager:IsPlayerRankSet(PlayerUUID) -> bool cLuaState S(L); @@ -601,7 +610,7 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) /** Binds cRankManager::RankExists */ static int tolua_cRankManager_RankExists(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RankExists(RankName) -> bool cLuaState S(L); @@ -633,7 +642,7 @@ static int tolua_cRankManager_RankExists(lua_State * L) /** Binds cRankManager::RemoveGroup */ static int tolua_cRankManager_RemoveGroup(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RemoveGroup(GroupName) cLuaState S(L); @@ -662,7 +671,7 @@ static int tolua_cRankManager_RemoveGroup(lua_State * L) /** Binds cRankManager::RemoveGroupFromRank */ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RemoveGroupFromRank(GroupName, RankName) cLuaState S(L); @@ -691,7 +700,7 @@ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) /** Binds cRankManager::RemovePermissionFromGroup */ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RemovePermissionFromGroup(Permission, GroupName) cLuaState S(L); @@ -720,7 +729,7 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) /** Binds cRankManager::RemovePlayerRank */ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RemovePlayerRank(PlayerUUID) cLuaState S(L); @@ -749,7 +758,7 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) /** Binds cRankManager::RemoveRank */ static int tolua_cRankManager_RemoveRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RemoveRank(RankName, [ReplacementRankName]) cLuaState S(L); @@ -779,7 +788,7 @@ static int tolua_cRankManager_RemoveRank(lua_State * L) /** Binds cRankManager::RenameGroup */ static int tolua_cRankManager_RenameGroup(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RenameGroup(OldName, NewName) cLuaState S(L); @@ -811,7 +820,7 @@ static int tolua_cRankManager_RenameGroup(lua_State * L) /** Binds cRankManager::RenameRank */ static int tolua_cRankManager_RenameRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:RenameRank(OldName, NewName) cLuaState S(L); @@ -843,7 +852,7 @@ static int tolua_cRankManager_RenameRank(lua_State * L) /** Binds cRankManager::SetPlayerRank */ static int tolua_cRankManager_SetPlayerRank(lua_State * L) { - // function signature: + // Function signature: // cRankManager:SetPlayerRank(PlayerUUID, PlayerName, RankName) cLuaState S(L); @@ -872,7 +881,7 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L) /** Binds cRankManager::SetRankVisuals */ static int tolua_cRankManager_SetRankVisuals(lua_State * L) { - // function signature: + // Function signature: // cRankManager:SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode) cLuaState S(L); -- cgit v1.2.3 From a56634799e1fb7eef3d2817bd7d9c1b42969e934 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Sun, 24 Aug 2014 15:03:02 +0200 Subject: Change comment formatting --- src/Entities/Minecart.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 13469edb3..f43c4d163 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -889,35 +889,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - // Moving -X +Z { + // Moving -X +Z if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - // ~ speedX >= 0 { - // Immobile or not moving in the "right" direction. Give it a bump! + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } else - // ~ SpeedX < 0 { - // Moving in the "right" direction. Only accelerate it a bit. + // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit. SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } } else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - // Moving +X -Z - // ~ SpeedX <= 0 { - // Immobile or not moving in the "right" direction + // Moving +X -T + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } else - // ~ SpeedX > 0 { - // Moving in the "right" direction + // ~ SpeedX > 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } @@ -942,35 +938,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) - // Moving +X +Z { + // Moving +X +Z if ((GetSpeedX() * 0.4) < 0.01) - // ~ SpeedX <= 0 { - // Immobile or not moving in the "right" direction + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } else - // SpeedX > 0 { - // Moving in the "right" direction + // ~ SpeedX > 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } } else if ((-GetSpeedX() * 0.4) < 0.01) - // Moving -X -Z - // ~ SpeedX >= 0 { - // Immobile or not moving in the "right" direction + // Moving -X -Z + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } else - // ~ SpeedX < 0 { - // Moving in the "right" direction + // ~ SpeedX < 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } -- cgit v1.2.3 From 8630b20c523033b359e4f9d7513cb6e4aafec1cb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 24 Aug 2014 20:00:45 +0200 Subject: RankMgr: Default rank is applied to players without any rank. --- src/Entities/Player.cpp | 6 ++++- src/RankManager.cpp | 69 +++++++++---------------------------------------- src/RankManager.h | 6 +++-- 3 files changed, 21 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 7992204da..b0dd40615 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2051,8 +2051,12 @@ void cPlayer::LoadRank(void) // Load the values from cRankManager: cRankManager & RankMgr = cRoot::Get()->GetRankManager(); m_Rank = RankMgr.GetPlayerRankName(m_UUID); + if (m_Rank.empty()) + { + m_Rank = RankMgr.GetDefaultRank(); + } m_Permissions = RankMgr.GetPlayerPermissions(m_UUID); - RankMgr.GetPlayerMsgVisuals(m_UUID, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); + RankMgr.GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); // Break up the individual permissions on each dot, into m_SplitPermissions: m_SplitPermissions.clear(); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 0cee7724b..65ce33b92 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -534,34 +534,12 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) { - ASSERT(m_IsInitialized); - cCSLock Lock(m_CS); - - AStringVector res; - try + AString Rank = GetPlayerRankName(a_PlayerUUID); + if (Rank.empty()) { - // Prepare the DB statement: - SQLite::Statement stmt(m_DB, - "SELECT DISTINCT(PermissionItem.Permission) FROM PermissionItem " - "LEFT JOIN RankPermGroup " - "ON PermissionItem.PermGroupID = RankPermGroup.PermGroupID " - "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankPermGroup.RankID " - "WHERE PlayerRank.PlayerUUID = ?" - ); - stmt.bind(1, a_PlayerUUID); - - // Execute and get results: - while (stmt.executeStep()) - { - res.push_back(stmt.getColumn(0).getText()); - } + Rank = m_DefaultRank; } - catch (const SQLite::Exception & ex) - { - LOGWARNING("%s: Cannot get player permissions: %s", __FUNCTION__, ex.what()); - } - return res; + return GetRankPermissions(Rank); } @@ -742,39 +720,16 @@ bool cRankManager::GetPlayerMsgVisuals( AString & a_MsgNameColorCode ) { - ASSERT(m_IsInitialized); - cCSLock Lock(m_CS); - - AStringVector res; - try - { - SQLite::Statement stmt(m_DB, - "SELECT Rank.MsgPrefix, Rank.MsgSuffix, Rank.MsgNameColorCode FROM Rank " - "LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID " - "WHERE PlayerRank.PlayerUUID = ?" - ); - stmt.bind(1, a_PlayerUUID); - if (!stmt.executeStep()) - { - LOGD("%s: Player UUID %s not found in the DB, returning empty values.", __FUNCTION__, a_PlayerUUID.c_str()); - a_MsgPrefix.clear(); - a_MsgSuffix.clear(); - a_MsgNameColorCode.clear(); - return false; - } - a_MsgPrefix = stmt.getColumn(0).getText(); - a_MsgSuffix = stmt.getColumn(1).getText(); - a_MsgNameColorCode = stmt.getColumn(2).getText(); - return true; - } - catch (const SQLite::Exception & ex) + AString Rank = GetPlayerRankName(a_PlayerUUID); + if (Rank.empty()) { - LOGWARNING("%s: Failed to get ranks from DB: %s. Returning empty values.", __FUNCTION__, ex.what()); + // Rank not found, return failure: + a_MsgPrefix.clear(); + a_MsgSuffix.clear(); + a_MsgNameColorCode.clear(); + return false; } - a_MsgPrefix.clear(); - a_MsgSuffix.clear(); - a_MsgNameColorCode.clear(); - return false; + return GetRankVisuals(Rank, a_MsgPrefix, a_MsgSuffix, a_MsgNameColorCode); } diff --git a/src/RankManager.h b/src/RankManager.h index b93a1157d..f364bba6a 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -56,13 +56,15 @@ public: The a_MojangAPI param is used when migrating from old ini files, to look up player UUIDs. */ void Initialize(cMojangAPI & a_MojangAPI); - /** Returns the name of the rank that the specified player has assigned to them. */ + /** Returns the name of the rank that the specified player has assigned to them. + If the player has no rank assigned, returns an empty string (NOT the default rank). */ AString GetPlayerRankName(const AString & a_PlayerUUID); /** Returns the names of Groups that the specified player has assigned to them. */ AStringVector GetPlayerGroups(const AString & a_PlayerUUID); - /** Returns the permissions that the specified player has assigned to them. */ + /** Returns the permissions that the specified player has assigned to them. + If the player has no rank assigned to them, returns the default rank's permissions. */ AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); /** Returns the names of groups that the specified rank has assigned to it. -- cgit v1.2.3 From 3977d53b8301108c4b121467647ddd6e2f2ddaea Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 24 Aug 2014 20:05:28 +0200 Subject: RankMgr: Exported the default-rank functions. --- src/Bindings/ManualBindings_RankManager.cpp | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index f25f87e46..2e93ad264 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -210,6 +210,30 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L) +/** Binds cRankManager::GetDefaultRank */ +static int tolua_cRankManager_GetDefaultRank(lua_State * L) +{ + // Function signature: + // cRankManager:GetDefaultRank() -> string + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Return the rank name: + S.Push(cRoot::Get()->GetRankManager().GetDefaultRank()); + return 1; +} + + + + + /** Binds cRankManager::GetGroupPermissions */ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) { @@ -849,6 +873,35 @@ static int tolua_cRankManager_RenameRank(lua_State * L) +/** Binds cRankManager::SetDefaultRank */ +static int tolua_cRankManager_SetDefaultRank(lua_State * L) +{ + // Function signature: + // cRankManager:SetDefaultRank(RankName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Set the rank, return the result: + S.Push(cRoot::Get()->GetRankManager().SetDefaultRank(RankName)); + return 0; +} + + + + + /** Binds cRankManager::SetPlayerRank */ static int tolua_cRankManager_SetPlayerRank(lua_State * L) { @@ -922,6 +975,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); + tolua_function(tolua_S, "GetDefaultRank", tolua_cRankManager_GetDefaultRank); tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); tolua_function(tolua_S, "GetPlayerGroups", tolua_cRankManager_GetPlayerGroups); tolua_function(tolua_S, "GetPlayerMsgVisuals", tolua_cRankManager_GetPlayerMsgVisuals); @@ -942,6 +996,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "RemoveRank", tolua_cRankManager_RemoveRank); tolua_function(tolua_S, "RenameGroup", tolua_cRankManager_RenameGroup); tolua_function(tolua_S, "RenameRank", tolua_cRankManager_RenameRank); + tolua_function(tolua_S, "SetDefaultRank", tolua_cRankManager_SetDefaultRank); tolua_function(tolua_S, "SetPlayerRank", tolua_cRankManager_SetPlayerRank); tolua_function(tolua_S, "SetRankVisuals", tolua_cRankManager_SetRankVisuals); tolua_endmodule(tolua_S); -- cgit v1.2.3 From 8f20c359cd1f1086d4c312273fe052404755584f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 25 Aug 2014 07:28:45 +0200 Subject: Fixed a type warning. --- src/Protocol/MojangAPI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 823ff5469..d107a8470 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -655,11 +655,11 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) } // Store the returned results into cache: - size_t JsonCount = root.size(); + Json::Value::UInt JsonCount = root.size(); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); - for (size_t idx = 0; idx < JsonCount; ++idx) + for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); -- cgit v1.2.3 From bf16c5ed92c7d45599099c4c3d628cee1a60f35f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 25 Aug 2014 18:25:39 +0300 Subject: Type warning fixes. --- src/Inventory.cpp | 2 +- src/Protocol/MojangAPI.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 8da3dea5f..832a079bc 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -106,7 +106,7 @@ int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks, bool a_tryT // When the item is a armor, try to set it directly to the armor slot. if (ItemCategory::IsArmor(a_Item.m_ItemType)) { - for (size_t i = 0; i < (size_t)m_ArmorSlots.GetNumSlots(); i++) + for (int i = 0; i < m_ArmorSlots.GetNumSlots(); i++) { if (m_ArmorSlots.GetSlot(i).IsEmpty() && cSlotAreaArmor::CanPlaceArmorInSlot(i, a_Item)) { diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index d107a8470..83c2dc300 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -675,7 +675,7 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) // Also cache the UUIDToName: { cCSLock Lock(m_CSUUIDToName); - for (size_t idx = 0; idx < JsonCount; ++idx) + for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); -- cgit v1.2.3 From ac4d3a30ed76a7e139eac02de9edcb9fdbbf7957 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 26 Aug 2014 15:16:33 +0300 Subject: Added initial dungeon rooms finisher. --- src/Generating/CMakeLists.txt | 2 + src/Generating/ComposableGenerator.cpp | 8 ++ src/Generating/DungeonRoomsFinisher.cpp | 232 ++++++++++++++++++++++++++++++++ src/Generating/DungeonRoomsFinisher.h | 47 +++++++ 4 files changed, 289 insertions(+) create mode 100644 src/Generating/DungeonRoomsFinisher.cpp create mode 100644 src/Generating/DungeonRoomsFinisher.h (limited to 'src') diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt index 58df9d421..33d622b42 100644 --- a/src/Generating/CMakeLists.txt +++ b/src/Generating/CMakeLists.txt @@ -12,6 +12,7 @@ SET (SRCS CompoGen.cpp ComposableGenerator.cpp DistortedHeightmap.cpp + DungeonRoomsFinisher.cpp EndGen.cpp FinishGen.cpp GridStructGen.cpp @@ -40,6 +41,7 @@ SET (HDRS CompoGen.h ComposableGenerator.h DistortedHeightmap.h + DungeonRoomsFinisher.h EndGen.h FinishGen.h GridStructGen.h diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 2f575fe27..a3a9f170d 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -19,6 +19,7 @@ #include "Caves.h" #include "DistortedHeightmap.h" +#include "DungeonRoomsFinisher.h" #include "EndGen.h" #include "MineShafts.h" #include "NetherFortGen.h" @@ -343,6 +344,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); } + else if (NoCaseCompare(*itr, "DungeonRooms") == 0) + { + int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48); + int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); + int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); + m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize)); + } else if (NoCaseCompare(*itr, "Ice") == 0) { m_FinishGens.push_back(new cFinishGenIce); diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp new file mode 100644 index 000000000..37409d486 --- /dev/null +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -0,0 +1,232 @@ + +// DungeonRoomsFinisher.cpp + +// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms + +#include "Globals.h" +#include "DungeonRoomsFinisher.h" + + + + + +/** Height, in blocks, of the internal dungeon room open space. This many air blocks Y-wise. */ +static const int ROOM_HEIGHT = 4; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cDungeonRoom: + +class cDungeonRoom : + public cGridStructGen::cStructure +{ + typedef cGridStructGen::cStructure super; + +public: + + cDungeonRoom( + int a_GridX, int a_GridZ, + int a_OriginX, int a_OriginZ, + int a_HalfSizeX, int a_HalfSizeZ, + int a_FloorHeight, + cNoise & a_Noise + ) : + super(a_GridX, a_GridZ, a_OriginX, a_OriginZ), + m_StartX(a_OriginX - a_HalfSizeX), + m_EndX(a_OriginX + a_HalfSizeX), + m_StartZ(a_OriginZ - a_HalfSizeZ), + m_EndZ(a_OriginZ + a_HalfSizeZ), + m_FloorHeight(a_FloorHeight), + m_Chest1(SelectChestCoords(a_Noise, a_OriginX + 1, a_OriginZ)), + m_Chest2(SelectChestCoords(a_Noise, a_OriginX + 2, a_OriginZ)) + { + } + +protected: + + // The X range of the room, start inclusive, end exclusive: + int m_StartX, m_EndX; + + // The Z range of the room, start inclusive, end exclusive: + int m_StartZ, m_EndZ; + + /** The Y coord of the floor of the room */ + int m_FloorHeight; + + /** The (absolute) coords of the first chest. The Y coord represents the chest's Meta value (facing). */ + Vector3i m_Chest1; + + /** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */ + Vector3i m_Chest2; + + + + /** Selects the coords for the chest, using the noise and coords provided. + Assumes that the room XZ ranges are already assigned. */ + Vector3i SelectChestCoords(cNoise & a_Noise, int a_X, int a_Z) + { + // Pick a coord next to the wall: + int rnd = a_Noise.IntNoise2DInt(a_X, a_Z) / 7; + int SizeX = m_EndX - m_StartX - 1; + int SizeZ = m_EndZ - m_StartZ - 1; + rnd = rnd % (2 * SizeX + 2 * SizeZ); + + if (rnd < SizeX) + { + // Return a coord on the ZM side of the room: + return Vector3i(m_StartX + rnd + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1); + } + rnd -= SizeX; + if (rnd < SizeZ) + { + // Return a coord on the XP side of the room: + return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + rnd + 1); + } + rnd -= SizeZ; + if (rnd < SizeX) + { + // Return a coord on the ZP side of the room: + return Vector3i(m_StartX + rnd + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1); + } + rnd -= SizeX; + // Return a coord on the XM side of the room: + return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + rnd + 1); + } + + + + /** Fills the specified area of blocks in the chunk with the specified blocktype if they are one of the overwritten block types. + The coords are absolute, start coords are inclusive, end coords are exclusive. */ + void ReplaceCuboid(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType) + { + int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1); + int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1); + int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width); + int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width); + for (int y = a_StartY; y < a_EndY; y++) + { + for (int z = RelStartZ; z < RelEndZ; z++) + { + for (int x = RelStartX; x < RelEndX; x++) + { + switch (a_ChunkDesc.GetBlockType(x, y, z)) + { + case E_BLOCK_STONE: + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_GRAVEL: + case E_BLOCK_SAND: + { + a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType); + break; + } + } // switch (GetBlockType) + } // for x + } // for z + } // for z + } + + + + /** Tries to place a chest at the specified (absolute) coords. + Does nothing if the coords are outside the chunk. */ + void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest) + { + int RelX = a_Chest.x - a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int RelZ = a_Chest.z - a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + if ( + (RelX < 0) || (RelX >= cChunkDef::Width) || // The X coord is not in this chunk + (RelZ < 0) || (RelZ >= cChunkDef::Width) // The Z coord is not in this chunk + ) + { + return; + } + a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y); + + // TODO: Fill the chest with random loot + } + + + + // cGridStructGen::cStructure override: + virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override + { + if ( + (m_EndX <= a_ChunkDesc.GetChunkX() * cChunkDef::Width) || + (m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) || + (m_EndZ <= a_ChunkDesc.GetChunkZ() * cChunkDef::Width) || + (m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width) + ) + { + // The chunk is not intersecting the room at all, bail out + return; + } + int b = m_FloorHeight + 1; // Bottom + int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top + ReplaceCuboid(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE); // Floor + ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR); // Insides + ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XM wall + ReplaceCuboid(a_ChunkDesc, m_EndX, b, m_StartZ, m_EndX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XP wall + ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1, t, m_StartZ + 1, E_BLOCK_COBBLESTONE); // ZM wall + ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ, m_EndX + 1, t, m_EndZ + 1, E_BLOCK_COBBLESTONE); // ZP wall + TryPlaceChest(a_ChunkDesc, m_Chest1); + TryPlaceChest(a_ChunkDesc, m_Chest2); + } +} ; + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cDungeonRoomsFinisher: + +cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize) : + super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), + m_HeightGen(a_HeightGen), + m_MaxHalfSize((a_MaxSize + 1) / 2), + m_MinHalfSize((a_MinSize + 1) / 2) +{ + // Normalize the min and max size: + if (m_MinHalfSize > m_MaxHalfSize) + { + std::swap(m_MinHalfSize, m_MaxHalfSize); + } +} + + + + + + +cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) +{ + // Select a random room size in each direction: + int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7; + int HalfSizeX = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1)); + rnd = rnd / 32; + int HalfSizeZ = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1)); + rnd = rnd / 32; + + // Select a random floor height for the room, based on the height generator: + int ChunkX, ChunkZ; + int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; + cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); + cChunkDef::HeightMap HeightMap; + m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); + int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} + Height = 10 + (rnd % std::max(1, (Height - 14))); + + // Create the dungeon room descriptor: + return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise)); +} + + + + diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h new file mode 100644 index 000000000..542a39682 --- /dev/null +++ b/src/Generating/DungeonRoomsFinisher.h @@ -0,0 +1,47 @@ + +// DungeonRoomsFinisher.h + +// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms + + + + + +#pragma once + +#include "GridStructGen.h" + + + + + +class cDungeonRoomsFinisher : + public cGridStructGen +{ + typedef cGridStructGen super; + +public: + /** Creates a new dungeon room finisher. + a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. + a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. */ + cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize); + +protected: + + /** The height gen that is used for limiting the rooms' Y coords */ + cTerrainHeightGen & m_HeightGen; + + /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */ + int m_MaxHalfSize; + + /** Minimum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 2 (vanilla). */ + int m_MinHalfSize; + + + // cGridStructGen overrides: + virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; +} ; + + + + -- cgit v1.2.3 From 2d569ce6ddae1e4d133ed79feeaefa53b5d6999b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 26 Aug 2014 17:13:46 +0300 Subject: DungeonRooms: Replaced explicit switch with CanBeTerraformed(). --- src/Generating/DungeonRoomsFinisher.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 37409d486..c662ca6b4 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -114,18 +114,10 @@ protected: { for (int x = RelStartX; x < RelEndX; x++) { - switch (a_ChunkDesc.GetBlockType(x, y, z)) + if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z))) { - case E_BLOCK_STONE: - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - case E_BLOCK_GRAVEL: - case E_BLOCK_SAND: - { - a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType); - break; - } - } // switch (GetBlockType) + a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType); + } } // for x } // for z } // for z -- cgit v1.2.3 From a40f3580641488c0dc2df65154e47a1b79b26470 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 26 Aug 2014 17:25:38 +0300 Subject: DungeonRooms: Random pattern for floors. --- src/Generating/DungeonRoomsFinisher.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index c662ca6b4..4dbbb0a11 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "DungeonRoomsFinisher.h" +#include "../FastRandom.h" @@ -125,6 +126,35 @@ protected: + /** Fills the specified area of blocks in the chunk with a random pattern of the specified blocktypes, if they are one of the overwritten block types. + The coords are absolute, start coords are inclusive, end coords are exclusive. The first blocktype uses 75% chance, the second 25% chance. */ + void ReplaceCuboidRandom(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType1, BLOCKTYPE a_DstBlockType2) + { + int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1); + int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1); + int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width); + int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width); + cFastRandom rnd; + for (int y = a_StartY; y < a_EndY; y++) + { + for (int z = RelStartZ; z < RelEndZ; z++) + { + for (int x = RelStartX; x < RelEndX; x++) + { + if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z))) + { + BLOCKTYPE BlockType = (rnd.NextInt(101) < 75) ? a_DstBlockType1 : a_DstBlockType2; + a_ChunkDesc.SetBlockType(x, y, z, BlockType); + } + } // for x + } // for z + } // for z + } + + + /** Tries to place a chest at the specified (absolute) coords. Does nothing if the coords are outside the chunk. */ void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest) @@ -160,8 +190,9 @@ protected: } int b = m_FloorHeight + 1; // Bottom int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top - ReplaceCuboid(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE); // Floor + ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR); // Insides + // Walls: ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XM wall ReplaceCuboid(a_ChunkDesc, m_EndX, b, m_StartZ, m_EndX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XP wall ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1, t, m_StartZ + 1, E_BLOCK_COBBLESTONE); // ZM wall -- cgit v1.2.3 From 0c3c136c72da69c0d100b40689fa931c197fb522 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 26 Aug 2014 17:46:14 +0300 Subject: DungeonRooms: Chests are never placed next to each other. --- src/Generating/DungeonRoomsFinisher.cpp | 49 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 4dbbb0a11..f4fb9b222 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -40,10 +40,22 @@ public: m_EndX(a_OriginX + a_HalfSizeX), m_StartZ(a_OriginZ - a_HalfSizeZ), m_EndZ(a_OriginZ + a_HalfSizeZ), - m_FloorHeight(a_FloorHeight), - m_Chest1(SelectChestCoords(a_Noise, a_OriginX + 1, a_OriginZ)), - m_Chest2(SelectChestCoords(a_Noise, a_OriginX + 2, a_OriginZ)) + m_FloorHeight(a_FloorHeight) { + /* + Pick coords next to the wall for the chests. + This is done by indexing the possible coords, picking any one for the first chest + and then picking another position for the second chest that is not adjacent to the first pos + */ + int rnd = a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7; + int SizeX = m_EndX - m_StartX - 1; + int SizeZ = m_EndZ - m_StartZ - 1; + int NumPositions = 2 * SizeX + 2 * SizeZ; + int FirstChestPos = rnd % NumPositions; // The corner positions are a bit more likely, but we don't mind + rnd = rnd / 512; + int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions; + m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ); + m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ); } protected: @@ -65,36 +77,29 @@ protected: - /** Selects the coords for the chest, using the noise and coords provided. - Assumes that the room XZ ranges are already assigned. */ - Vector3i SelectChestCoords(cNoise & a_Noise, int a_X, int a_Z) + /** Decodes the position index along the room walls into a proper 2D position for a chest. */ + Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ) { - // Pick a coord next to the wall: - int rnd = a_Noise.IntNoise2DInt(a_X, a_Z) / 7; - int SizeX = m_EndX - m_StartX - 1; - int SizeZ = m_EndZ - m_StartZ - 1; - rnd = rnd % (2 * SizeX + 2 * SizeZ); - - if (rnd < SizeX) + if (a_PosIdx < a_SizeX) { // Return a coord on the ZM side of the room: - return Vector3i(m_StartX + rnd + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1); + return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1); } - rnd -= SizeX; - if (rnd < SizeZ) + a_PosIdx -= a_SizeX; + if (a_PosIdx < a_SizeZ) { // Return a coord on the XP side of the room: - return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + rnd + 1); + return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + a_PosIdx + 1); } - rnd -= SizeZ; - if (rnd < SizeX) + a_PosIdx -= a_SizeZ; + if (a_PosIdx < a_SizeX) { // Return a coord on the ZP side of the room: - return Vector3i(m_StartX + rnd + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1); + return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1); } - rnd -= SizeX; + a_PosIdx -= a_SizeX; // Return a coord on the XM side of the room: - return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + rnd + 1); + return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + a_PosIdx + 1); } -- cgit v1.2.3 From c6beb9760bcfb86ac03317dbb252e0478107d009 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 08:12:26 +0300 Subject: DungeonRooms: Added the spawner in the center of the room. --- src/Generating/DungeonRoomsFinisher.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index f4fb9b222..9555ee86c 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -197,13 +197,28 @@ protected: int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR); // Insides + // Walls: ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XM wall ReplaceCuboid(a_ChunkDesc, m_EndX, b, m_StartZ, m_EndX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XP wall ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1, t, m_StartZ + 1, E_BLOCK_COBBLESTONE); // ZM wall ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ, m_EndX + 1, t, m_EndZ + 1, E_BLOCK_COBBLESTONE); // ZP wall + + // Place chests: TryPlaceChest(a_ChunkDesc, m_Chest1); TryPlaceChest(a_ChunkDesc, m_Chest2); + + // Place the spawner: + int CenterX = (m_StartX + m_EndX) / 2 - a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int CenterZ = (m_StartZ + m_EndZ) / 2 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + if ( + (CenterX >= 0) && (CenterX < cChunkDef::Width) && + (CenterZ >= 0) && (CenterZ < cChunkDef::Width) + ) + { + a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0); + // TODO: Set the spawned mob + } } } ; -- cgit v1.2.3 From 62e1c45ca5352205679a60e963853e8511799657 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 13:25:27 +0300 Subject: DungeonRooms: Added a height probability distribution function. --- src/Generating/ComposableGenerator.cpp | 9 +++++---- src/Generating/DungeonRoomsFinisher.cpp | 10 +++++++--- src/Generating/DungeonRoomsFinisher.h | 9 +++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index a3a9f170d..6f4007d24 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -346,10 +346,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "DungeonRooms") == 0) { - int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48); - int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); - int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); - m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize)); + int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48); + int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); + int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); + AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); + m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)); } else if (NoCaseCompare(*itr, "Ice") == 0) { diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 9555ee86c..9e039d737 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -230,12 +230,16 @@ protected: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cDungeonRoomsFinisher: -cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize) : +cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), m_HeightGen(a_HeightGen), m_MaxHalfSize((a_MaxSize + 1) / 2), - m_MinHalfSize((a_MinSize + 1) / 2) + m_MinHalfSize((a_MinSize + 1) / 2), + m_HeightProbability(cChunkDef::Height) { + // Initialize the height probability distribution: + m_HeightProbability.SetDefString(a_HeightDistrib); + // Normalize the min and max size: if (m_MinHalfSize > m_MaxHalfSize) { @@ -264,7 +268,7 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int cChunkDef::HeightMap HeightMap; m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} - Height = 10 + (rnd % std::max(1, (Height - 14))); + Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); // Create the dungeon room descriptor: return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise)); diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h index 542a39682..2b52c9de6 100644 --- a/src/Generating/DungeonRoomsFinisher.h +++ b/src/Generating/DungeonRoomsFinisher.h @@ -10,6 +10,7 @@ #pragma once #include "GridStructGen.h" +#include "../ProbabDistrib.h" @@ -23,8 +24,9 @@ class cDungeonRoomsFinisher : public: /** Creates a new dungeon room finisher. a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. - a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. */ - cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize); + a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. + a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */ + cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); protected: @@ -37,6 +39,9 @@ protected: /** Minimum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 2 (vanilla). */ int m_MinHalfSize; + /** The height probability distribution to make the spawners more common in layers 10 - 40, less common outside this range. */ + cProbabDistrib m_HeightProbability; + // cGridStructGen overrides: virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; -- cgit v1.2.3 From bc44b96059291629b2bc6d1f6c71492fdc1974ed Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 15:12:49 +0300 Subject: CheckBasicStyle: Relaxed the "space after comma". An apostrophe directly following a comma is not a violation. --- src/CheckBasicStyle.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index bf81a7cd5..08f014e33 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -108,7 +108,7 @@ local g_ViolationPatterns = -- Check that all commas have spaces after them and not in front of them: {" ,", "Extra space before a \",\""}, - {",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting + {",[^%s\"%%\']", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting -- Check that opening braces are not at the end of a code line: {"[^%s].-{\n?$", "Brace should be on a separate line"}, -- cgit v1.2.3 From d8527c5429aa7ecaa31cc78c8c2fd3833d59266d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 15:13:13 +0300 Subject: Fixed basic style violations. --- src/LoggerListeners.cpp | 14 +++++++------- src/RankManager.cpp | 10 ++++------ 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index 836536cbd..77e2aaf67 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -65,7 +65,7 @@ { case cLogger::llRegular: { - // Gray on black + // Gray on black Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; break; } @@ -93,7 +93,7 @@ virtual void SetDefaultLogColour() override - { + { SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); } @@ -119,13 +119,13 @@ { case cLogger::llRegular: { - // Whatever the console default is + // Whatever the console default is printf("\x1b[0m"); - break; + break; } case cLogger::llInfo: { - // Yellow on black + // Yellow on black printf("\x1b[33;1m"); break; } @@ -133,7 +133,7 @@ { // Red on black printf("\x1b[31;1m"); - break; + break; } case cLogger::llError: { @@ -147,7 +147,7 @@ virtual void SetDefaultLogColour() override { - // Whatever the console default is + // Whatever the console default is printf("\x1b[0m"); } }; diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 65ce33b92..dc6eec9e4 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -125,7 +125,7 @@ protected: /** Maps lists of groups to rank names. Each group list is either a simple "" if there's only one group, - or ",,...", where the secondary groups are + or ", , ...", where the secondary groups are lowercased and alpha-sorted. This makes the group lists comparable for equivalence, simply by comparing their string names. The ranks are named "" for single-group players, and "AutoMigratedRank_N" for the composite ranks, @@ -507,10 +507,8 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) // Prepare the DB statement: SQLite::Statement stmt(m_DB, "SELECT PermGroup.Name FROM PermGroup " - "LEFT JOIN RankPermGroup " - "ON PermGroup.PermGroupID = RankPermGroup.PermGroupID " - "LEFT JOIN PlayerRank " - "ON PlayerRank.RankID = RankPermGroup.RankID " + "LEFT JOIN RankPermGroup ON PermGroup.PermGroupID = RankPermGroup.PermGroupID " + "LEFT JOIN PlayerRank ON PlayerRank.RankID = RankPermGroup.RankID " "WHERE PlayerRank.PlayerUUID = ?" ); stmt.bind(1, a_PlayerUUID); @@ -1473,7 +1471,7 @@ void cRankManager::RemovePlayerRank(const AString & a_PlayerUUID) stmt.bind(1, a_PlayerUUID); stmt.exec(); } - catch(const SQLite::Exception & ex) + catch (const SQLite::Exception & ex) { LOGWARNING("%s: Failed to remove rank from player UUID %s: %s", __FUNCTION__, a_PlayerUUID.c_str(), ex.what() -- cgit v1.2.3 From e54a7dc6c4e46c0c657cbd13242253cd1f08102a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 15:21:20 +0300 Subject: More basic style fixes. --- src/Generating/DungeonRoomsFinisher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 9e039d737..694dcc3cc 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -18,7 +18,7 @@ static const int ROOM_HEIGHT = 4; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cDungeonRoom: class cDungeonRoom : @@ -227,7 +227,7 @@ protected: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cDungeonRoomsFinisher: cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : -- cgit v1.2.3 From e54c78923e26e50f8e8839ce352def05a929d9a1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 20:55:28 +0300 Subject: DungeonRooms: Fixed an off-by-one error. --- src/Generating/DungeonRoomsFinisher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp index 694dcc3cc..f213455d6 100644 --- a/src/Generating/DungeonRoomsFinisher.cpp +++ b/src/Generating/DungeonRoomsFinisher.cpp @@ -184,9 +184,9 @@ protected: virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override { if ( - (m_EndX <= a_ChunkDesc.GetChunkX() * cChunkDef::Width) || + (m_EndX < a_ChunkDesc.GetChunkX() * cChunkDef::Width) || (m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) || - (m_EndZ <= a_ChunkDesc.GetChunkZ() * cChunkDef::Width) || + (m_EndZ < a_ChunkDesc.GetChunkZ() * cChunkDef::Width) || (m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width) ) { -- cgit v1.2.3 From 690e6cb6f8d0c67f3725de8398659115ab823f4c Mon Sep 17 00:00:00 2001 From: reiter Date: Thu, 28 Aug 2014 00:01:01 +0200 Subject: Fixed mob burning. Fixes #1298 --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index fe8a7346f..f7ee0b0c0 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -1024,7 +1024,7 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk) (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand (GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime !IsOnFire() && // Not already burning - GetWorld()->IsWeatherWetAt(POSX_TOINT, POSZ_TOINT) // Not raining + GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) // Not raining ) { // Burn for 100 ticks, then decide again -- cgit v1.2.3 From 0f1fd3312332da2a6104c9eb98625610a4a08eff Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 01:21:54 +0200 Subject: Enchanting table improvements. --- src/Item.cpp | 32 ++++----- src/UI/SlotArea.cpp | 192 +++++++++++++++++++++------------------------------- src/UI/SlotArea.h | 7 +- src/UI/Window.cpp | 33 +++++---- src/UI/Window.h | 3 - 5 files changed, 113 insertions(+), 154 deletions(-) (limited to 'src') diff --git a/src/Item.cpp b/src/Item.cpp index 2c5deaddf..a5117c271 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -190,31 +190,23 @@ void cItem::FromJson(const Json::Value & a_Value) -bool cItem::IsEnchantable(short item) +bool cItem::IsEnchantable(short a_ItemType) { - if ((item >= 256) && (item <= 259)) + if (ItemCategory::IsTool(a_ItemType) || ItemCategory::IsArmor(a_ItemType)) { return true; } - if ((item >= 267) && (item <= 279)) - { - return true; - } - if ((item >= 283) && (item <= 286)) - { - return true; - } - if ((item >= 290) && (item <= 294)) - { - return true; - } - if ((item >= 298) && (item <= 317)) - { - return true; - } - if ((item == 346) || (item == 359) || (item == 261)) + + switch (a_ItemType) { - return true; + case E_ITEM_BOOK: + case E_ITEM_BOW: + case E_ITEM_CARROT_ON_STICK: + case E_ITEM_FISHING_ROD: + case E_ITEM_SHEARS: + { + return true; + } } return false; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 4199bbf56..74173d087 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -207,7 +207,7 @@ void cSlotArea::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ m_ParentWindow.DistributeStack(Slot, a_Player, this, true); if (Slot.IsEmpty()) { - // Empty the slot completely, the cilent doesn't like left-over ItemType with zero count + // Empty the slot completely, the client doesn't like left-over ItemType with zero count Slot.Empty(); } SetSlot(a_SlotNum, a_Player, Slot); @@ -1389,8 +1389,11 @@ void cSlotAreaBeacon::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) //////////////////////////////////////////////////////////////////////////////// // cSlotAreaEnchanting: -cSlotAreaEnchanting::cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow) : - cSlotAreaTemporary(1, a_ParentWindow) +cSlotAreaEnchanting::cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow, int a_BlockX, int a_BlockY, int a_BlockZ) : + cSlotAreaTemporary(1, a_ParentWindow), + m_BlockX(a_BlockX), + m_BlockY(a_BlockY), + m_BlockZ(a_BlockZ) { a_ParentWindow.m_SlotArea = this; } @@ -1409,7 +1412,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum); return; } - + switch (a_ClickAction) { case caShiftLeftClick: @@ -1420,7 +1423,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio } case caDblClick: { - DblClicked(a_Player, a_SlotNum); + // DblClicked(a_Player, a_SlotNum); return; } case caMiddleClick: @@ -1428,6 +1431,25 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio MiddleClicked(a_Player, a_SlotNum); return; } + case caDropKey: + case caCtrlDropKey: + { + DropClicked(a_Player, a_SlotNum, false); + return; + } + case caNumber1: + case caNumber2: + case caNumber3: + case caNumber4: + case caNumber5: + case caNumber6: + case caNumber7: + case caNumber8: + case caNumber9: + { + NumberClicked(a_Player, a_SlotNum, a_ClickAction); + return; + } default: { break; @@ -1443,106 +1465,37 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio bAsync = true; } cItem & DraggingItem = a_Player.GetDraggingItem(); - switch (a_ClickAction) + + if (DraggingItem.IsEmpty()) { - case caRightClick: - { - // Right-clicked - if (DraggingItem.IsEmpty()) - { - DraggingItem = Slot.CopyOne(); - Slot.Empty(); - break; - } - - if (Slot.IsEmpty()) - { - Slot = DraggingItem.CopyOne(); - DraggingItem.m_ItemCount -= 1; - if (DraggingItem.m_ItemCount <= 0) - { - DraggingItem.Empty(); - } - } - else if ((!DraggingItem.IsEqual(Slot)) && (DraggingItem.m_ItemCount == 1)) - { - // Swap contents - cItem tmp(DraggingItem); - DraggingItem = Slot; - Slot = tmp; - } - break; - } - - case caLeftClick: + if (!Slot.IsEmpty()) { - // Left-clicked - if (DraggingItem.IsEmpty()) - { - DraggingItem = Slot.CopyOne(); - Slot.Empty(); - break; - } - - if (DraggingItem.IsEqual(Slot)) - { - // Do nothing - break; - } - - if (!Slot.IsEmpty()) - { - if (DraggingItem.m_ItemCount == 1) - { - // Swap contents - cItem tmp(DraggingItem); - DraggingItem = Slot; - Slot = tmp; - } - } - else - { - Slot = DraggingItem.CopyOne(); - DraggingItem.m_ItemCount -= 1; - if (DraggingItem.m_ItemCount <= 0) - { - DraggingItem.Empty(); - } - } - break; + DraggingItem = Slot; + Slot.Empty(); } - default: + } + else if (Slot.IsEmpty()) + { + Slot = DraggingItem.CopyOne(); + DraggingItem.m_ItemCount -= 1; + + if (DraggingItem.m_ItemCount <= 0) { - LOGWARNING("SlotArea: Unhandled click action: %d (%s)", a_ClickAction, ClickActionToString(a_ClickAction)); - m_ParentWindow.BroadcastWholeWindow(); - return; + DraggingItem.Empty(); } - } // switch (a_ClickAction - - SetSlot(a_SlotNum, a_Player, Slot); - if (bAsync) - { - m_ParentWindow.BroadcastWholeWindow(); } - UpdateResult(a_Player); -} - - - - - -void cSlotAreaEnchanting::DblClicked(cPlayer & a_Player, int a_SlotNum) -{ - cItem & Dragging = a_Player.GetDraggingItem(); - if ((!Dragging.IsEmpty()) || (a_SlotNum != 0)) + else if ((DraggingItem.m_ItemCount == 1) && !DraggingItem.IsEqual(Slot)) { - return; + // Switch contents + cItem tmp(DraggingItem); + DraggingItem = Slot; + Slot = tmp; } - - cItem Item = *GetSlot(0, a_Player); - if (!m_ParentWindow.CollectItemsToHand(Item, *this, a_Player, false)) + + SetSlot(a_SlotNum, a_Player, Slot); + if (bAsync) { - m_ParentWindow.CollectItemsToHand(Item, *this, a_Player, true); + m_ParentWindow.BroadcastWholeWindow(); } } @@ -1567,7 +1520,15 @@ void cSlotAreaEnchanting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Playe { a_ItemStack.Empty(); } +} + + + + +void cSlotAreaEnchanting::OnPlayerAdded(cPlayer & a_Player) +{ + super::OnPlayerAdded(a_Player); UpdateResult(a_Player); } @@ -1587,29 +1548,33 @@ void cSlotAreaEnchanting::OnPlayerRemoved(cPlayer & a_Player) +void cSlotAreaEnchanting::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) +{ + super::SetSlot(a_SlotNum, a_Player, a_Item); + UpdateResult(a_Player); +} + + + + + void cSlotAreaEnchanting::UpdateResult(cPlayer & a_Player) { cItem Item = *GetSlot(0, a_Player); - if (Item.IsEmpty() || !Item.m_Enchantments.IsEmpty()) - { - m_ParentWindow.SetProperty(0, 0, a_Player); - m_ParentWindow.SetProperty(1, 0, a_Player); - m_ParentWindow.SetProperty(2, 0, a_Player); - } - else if (cItem::IsEnchantable(Item.m_ItemType) || Item.m_ItemType == E_ITEM_BOOK) + if (cItem::IsEnchantable(Item.m_ItemType) && Item.m_Enchantments.IsEmpty()) { int Bookshelves = std::min(GetBookshelvesCount(a_Player.GetWorld()), 15); cFastRandom Random; - int base = (Random.GenerateRandomInteger(1, 8) + (int)floor((float)Bookshelves / 2) + Random.GenerateRandomInteger(0, Bookshelves)); - int topSlot = std::max(base / 3, 1); - int middleSlot = (base * 2) / 3 + 1; - int bottomSlot = std::max(base, Bookshelves * 2); + int Base = (Random.GenerateRandomInteger(1, 8) + (int)floor((float)Bookshelves / 2) + Random.GenerateRandomInteger(0, Bookshelves)); + int TopSlot = std::max(Base / 3, 1); + int MiddleSlot = (Base * 2) / 3 + 1; + int BottomSlot = std::max(Base, Bookshelves * 2); - m_ParentWindow.SetProperty(0, topSlot, a_Player); - m_ParentWindow.SetProperty(1, middleSlot, a_Player); - m_ParentWindow.SetProperty(2, bottomSlot, a_Player); + m_ParentWindow.SetProperty(0, TopSlot, a_Player); + m_ParentWindow.SetProperty(1, MiddleSlot, a_Player); + m_ParentWindow.SetProperty(2, BottomSlot, a_Player); } else { @@ -1625,12 +1590,9 @@ void cSlotAreaEnchanting::UpdateResult(cPlayer & a_Player) int cSlotAreaEnchanting::GetBookshelvesCount(cWorld * a_World) { - int PosX, PosY, PosZ; - ((cEnchantingWindow*)&m_ParentWindow)->GetBlockPos(PosX, PosY, PosZ); - int Bookshelves = 0; cBlockArea Area; - Area.Read(a_World, PosX - 2, PosX + 2, PosY, PosY + 1, PosZ - 2, PosZ + 2); + Area.Read(a_World, m_BlockX - 2, m_BlockX + 2, m_BlockY, m_BlockY + 1, m_BlockZ - 2, m_BlockZ + 2); static const struct { @@ -1678,7 +1640,7 @@ int cSlotAreaEnchanting::GetBookshelvesCount(cWorld * a_World) if ( (Area.GetRelBlockType(CheckCoords[i].m_AirX, CheckCoords[i].m_AirY, CheckCoords[i].m_AirZ) == E_BLOCK_AIR) && // There's air in the checkspot (Area.GetRelBlockType(CheckCoords[i].m_BookX, CheckCoords[i].m_BookY, CheckCoords[i].m_BookZ) == E_BLOCK_BOOKCASE) // There's bookcase in the wanted place - ) + ) { Bookshelves++; } diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 9a96f2f3c..6bbc87b76 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -349,14 +349,15 @@ class cSlotAreaEnchanting : typedef cSlotAreaTemporary super; public: - cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow); + cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow, int a_BlockX, int a_BlockY, int a_BlockZ); // cSlotArea overrides: virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; - virtual void DblClicked(cPlayer & a_Player, int a_SlotNum) override; virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override; + virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; // cSlotAreaTemporary overrides: + virtual void OnPlayerAdded (cPlayer & a_Player) override; virtual void OnPlayerRemoved(cPlayer & a_Player) override; /* Get the count of bookshelves who stand in the near of the enchanting table */ @@ -365,6 +366,8 @@ public: protected: /** Handles a click in the item slot. */ void UpdateResult(cPlayer & a_Player); + + int m_BlockX, m_BlockY, m_BlockZ; }; diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 8f4913030..66900269f 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -881,7 +881,7 @@ cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) : m_BlockY(a_BlockY), m_BlockZ(a_BlockZ) { - m_SlotAreas.push_back(new cSlotAreaEnchanting(*this)); + m_SlotAreas.push_back(new cSlotAreaEnchanting(*this, m_BlockX, m_BlockY, m_BlockZ)); m_SlotAreas.push_back(new cSlotAreaInventory(*this)); m_SlotAreas.push_back(new cSlotAreaHotBar(*this)); } @@ -892,8 +892,13 @@ cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) : void cEnchantingWindow::SetProperty(int a_Property, int a_Value) { - m_PropertyValue[a_Property] = a_Value; + if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) + { + ASSERT(!"a_Property is invalid"); + return; + } + m_PropertyValue[a_Property] = a_Value; super::SetProperty(a_Property, a_Value); } @@ -903,8 +908,13 @@ void cEnchantingWindow::SetProperty(int a_Property, int a_Value) void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Player) { - m_PropertyValue[a_Property] = a_Value; + if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) + { + ASSERT(!"a_Property is invalid"); + return; + } + m_PropertyValue[a_Property] = a_Value; super::SetProperty(a_Property, a_Value, a_Player); } @@ -914,18 +924,13 @@ void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Pla int cEnchantingWindow::GetPropertyValue(int a_Property) { - return m_PropertyValue[a_Property]; -} - - - - + if ((a_Property < 0) || ((size_t)a_Property >= ARRAYCOUNT(m_PropertyValue))) + { + ASSERT(!"a_Property is invalid"); + return 0; + } -void cEnchantingWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ) -{ - a_PosX = m_BlockX; - a_PosY = m_BlockY; - a_PosZ = m_BlockZ; + return m_PropertyValue[a_Property]; } diff --git a/src/UI/Window.h b/src/UI/Window.h index 9fb0e3b38..3d860407f 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -291,9 +291,6 @@ public: /** Return the Value of a Property */ int GetPropertyValue(int a_Property); - /** Get the Position from the Enchantment Table */ - void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ); - cSlotArea * m_SlotArea; protected: -- cgit v1.2.3 From 3c1c073714e2b0542c9a79db962b6fc9e6ddd352 Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Thu, 28 Aug 2014 11:36:35 +0200 Subject: remove y-coord from chunks --- src/Bindings/LuaChunkStay.cpp | 2 +- src/Chunk.cpp | 7 +- src/Chunk.h | 2 +- src/ChunkDef.h | 6 +- src/ChunkMap.cpp | 258 +++++++++++++++++++------------------- src/ChunkMap.h | 14 +-- src/ChunkSender.cpp | 14 +-- src/ChunkSender.h | 7 +- src/ChunkStay.cpp | 2 +- src/ClientHandle.cpp | 20 +-- src/ClientHandle.h | 2 +- src/Generating/ChunkGenerator.cpp | 14 +-- src/Generating/ChunkGenerator.h | 4 +- src/World.cpp | 21 ++-- src/World.h | 6 +- src/WorldStorage/WSSCompact.cpp | 6 +- src/WorldStorage/WorldStorage.cpp | 28 ++--- src/WorldStorage/WorldStorage.h | 12 +- 18 files changed, 208 insertions(+), 217 deletions(-) (limited to 'src') diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 59b02d8f7..154bcb200 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -107,7 +107,7 @@ void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index) } } // for itr - m_Chunks[] - m_Chunks.push_back(cChunkCoords(ChunkX, ZERO_CHUNK_Y, ChunkZ)); + m_Chunks.push_back(cChunkCoords(ChunkX, ChunkZ)); } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 116c0f3a0..5fd6cb352 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -65,7 +65,7 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc // cChunk: cChunk::cChunk( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, + int a_ChunkX, int a_ChunkZ, cChunkMap * a_ChunkMap, cWorld * a_World, cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, cAllocationPool & a_Pool @@ -77,7 +77,6 @@ cChunk::cChunk( m_HasLoadFailed(false), m_StayCount(0), m_PosX(a_ChunkX), - m_PosY(a_ChunkY), m_PosZ(a_ChunkZ), m_World(a_World), m_ChunkMap(a_ChunkMap), @@ -643,7 +642,7 @@ void cChunk::MoveEntityToNewChunk(cEntity * a_Entity) cChunk * Neighbor = GetNeighborChunk(a_Entity->GetChunkX() * cChunkDef::Width, a_Entity->GetChunkZ() * cChunkDef::Width); if (Neighbor == NULL) { - Neighbor = m_ChunkMap->GetChunkNoLoad(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ()); + Neighbor = m_ChunkMap->GetChunkNoLoad(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if (Neighbor == NULL) { // TODO: What to do with this? @@ -2593,7 +2592,7 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ; int ChunkX, ChunkZ; BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); - return m_ChunkMap->GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + return m_ChunkMap->GetChunkNoLoad(ChunkX, ChunkZ); } // Walk the neighbors: diff --git a/src/Chunk.h b/src/Chunk.h index 72a1f6c95..67b208fe5 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -67,7 +67,7 @@ class cChunk : { public: cChunk( - int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords + int a_ChunkX, int a_ChunkZ, // Chunk coords cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks cAllocationPool & a_Pool diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 51075ab4a..b7122efe2 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -19,7 +19,6 @@ /** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord. It will help us when the new chunk format comes out and we need to patch everything up for compatibility. */ -#define ZERO_CHUNK_Y 0 // Used to smoothly convert to new axis ordering. One will be removed when deemed stable. #define AXIS_ORDER_YZX 1 // Original (1.1-) @@ -377,14 +376,13 @@ class cChunkCoords { public: int m_ChunkX; - int m_ChunkY; int m_ChunkZ; - cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {} + cChunkCoords(int a_ChunkX, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ) {} bool operator == (const cChunkCoords & a_Other) const { - return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ)); + return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkZ == a_Other.m_ChunkZ)); } } ; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index dd8be0631..e4ce6cbf5 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -143,7 +143,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk(int a_ChunkX, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) { // No need to lock m_CSLayers, since it's already locked by the operation that called us ASSERT(m_CSLayers.IsLockedByCurrentThread()); @@ -155,14 +155,14 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) return NULL; } - cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return NULL; } if (!(Chunk->IsValid())) { - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, true); + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, true); } return Chunk; } @@ -171,7 +171,7 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ) +cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ) { // No need to lock m_CSLayers, since it's already locked by the operation that called us cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); @@ -181,14 +181,14 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ) return NULL; } - cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return NULL; } if (!(Chunk->IsValid())) { - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ, false); + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, false); } return Chunk; @@ -198,7 +198,7 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ) +cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkZ) { // No need to lock m_CSLayers, since it's already locked by the operation that called us cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); @@ -208,7 +208,7 @@ cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ) return NULL; } - return Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + return Layer->GetChunk(a_ChunkX, a_ChunkZ); } @@ -222,7 +222,7 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return false; @@ -244,7 +244,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return false; @@ -265,7 +265,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return false; @@ -284,7 +284,7 @@ bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY // We already have m_CSLayers locked since this can be called only from within the tick thread int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return false; @@ -303,7 +303,7 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO // We already have m_CSLayers locked since this can be called only from within the tick thread int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return false; @@ -336,7 +336,7 @@ cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ) void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -356,7 +356,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c x = a_BlockX; z = a_BlockZ; cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -375,7 +375,7 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -393,7 +393,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -408,7 +408,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, 0, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return; @@ -424,7 +424,7 @@ void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -440,7 +440,7 @@ void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -456,7 +456,7 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -472,7 +472,7 @@ void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -488,7 +488,7 @@ void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotN void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -504,7 +504,7 @@ void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -520,7 +520,7 @@ void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandl void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -536,7 +536,7 @@ void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -552,7 +552,7 @@ void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, ch void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -568,7 +568,7 @@ void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -584,7 +584,7 @@ void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, c void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -600,7 +600,7 @@ void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientH void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -619,7 +619,7 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_ int ChunkX, ChunkZ; cChunkDef::BlockToChunk((int) a_SrcX, (int) a_SrcZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -636,7 +636,7 @@ void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_Effe { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -655,7 +655,7 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, double a_X, do int ChunkX, ChunkZ; cChunkDef::BlockToChunk((int)std::floor(a_X), (int)std::floor(a_Z), ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -674,7 +674,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_SrcX, a_SrcZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -690,7 +690,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S void cChunkMap::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == NULL) { return; @@ -708,7 +708,7 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -727,7 +727,7 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -745,7 +745,7 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -763,7 +763,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -778,7 +778,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return false; @@ -795,7 +795,7 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -824,7 +824,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M int MaxZ = std::min(a_MaxBlockZ, z * cChunkDef::Width + cChunkDef::Width - 1); for (int x = MinChunkX; x <= MaxChunkX; x++) { - cChunkPtr Chunk = GetChunkNoGen(x, 0, z); + cChunkPtr Chunk = GetChunkNoGen(x, z); if ((Chunk == NULL) || !Chunk->IsValid()) { continue; @@ -852,7 +852,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M void cChunkMap::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -867,7 +867,7 @@ void cChunkMap::MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ) void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -886,7 +886,7 @@ void cChunkMap::MarkChunkDirty(int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDi void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -901,7 +901,7 @@ void cChunkMap::MarkChunkSaving(int a_ChunkX, int a_ChunkZ) void cChunkMap::MarkChunkSaved (int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -919,7 +919,7 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) int ChunkZ = a_SetChunkData.GetChunkZ(); { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk == NULL) { return; @@ -964,7 +964,7 @@ void cChunkMap::ChunkLighted( ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return; @@ -980,7 +980,7 @@ void cChunkMap::ChunkLighted( bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -996,7 +996,7 @@ bool cChunkMap::GetChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -1012,7 +1012,7 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blo bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); return (Chunk != NULL) && Chunk->IsValid(); } @@ -1023,7 +1023,7 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); return (Chunk != NULL) && Chunk->HasAnyClients(); } @@ -1038,7 +1038,7 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if (Chunk == NULL) { return 0; @@ -1065,7 +1065,7 @@ bool cChunkMap::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height) cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ, BlockY = 0; cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -1088,7 +1088,7 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList) int ChunkX = a_BlockList.front().ChunkX; int ChunkZ = a_BlockList.front().ChunkZ; cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { for (sSetBlockList::iterator itr = a_BlockList.begin(); itr != a_BlockList.end();) @@ -1135,7 +1135,7 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway int BlockY = (int)(a_Player->GetPosY()); int BlockZ = (int)(a_Player->GetPosZ()); - int ChunkX, ChunkZ, ChunkY = ZERO_CHUNK_Y; + int ChunkX = 0, ChunkZ = 0; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1); @@ -1144,13 +1144,13 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment cCSLock Lock(m_CSLayers); - GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkZ)->CollectPickupsByPlayer(a_Player); // Check the neighboring chunks as well: - GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer (a_Player); - GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); - GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer (a_Player); - GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(OtherChunkX, ChunkZ)->CollectPickupsByPlayer (a_Player); + GetChunkNoLoad(OtherChunkX, OtherChunkZ)->CollectPickupsByPlayer(a_Player); + GetChunkNoLoad(ChunkX, ChunkZ)->CollectPickupsByPlayer (a_Player); + GetChunkNoLoad(ChunkX, OtherChunkZ)->CollectPickupsByPlayer(a_Player); } @@ -1177,7 +1177,7 @@ BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); @@ -1206,7 +1206,7 @@ NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -1224,7 +1224,7 @@ NIBBLETYPE cChunkMap::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetSkyLight(a_BlockX, a_BlockY, a_BlockZ); @@ -1242,7 +1242,7 @@ NIBBLETYPE cChunkMap::GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_Block cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetBlockLight(a_BlockX, a_BlockY, a_BlockZ); @@ -1261,7 +1261,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP // a_BlockXYZ now contains relative coords! cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->SetMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); @@ -1284,7 +1284,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients); @@ -1303,7 +1303,7 @@ void cChunkMap::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYP cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->QueueSetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_Tick, a_PreviousBlockType); @@ -1320,7 +1320,7 @@ bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->GetBlockTypeMeta(X, Y, Z, a_BlockType, a_BlockMeta); @@ -1339,7 +1339,7 @@ bool cChunkMap::GetBlockInfo(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk( ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->GetBlockInfo(X, Y, Z, a_BlockType, a_Meta, a_SkyLight, a_BlockLight); @@ -1357,7 +1357,7 @@ void cChunkMap::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_Filt cCSLock Lock(m_CSLayers); for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ); + cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { continue; @@ -1378,7 +1378,7 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) cCSLock Lock(m_CSLayers); for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ); + cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { continue; @@ -1413,7 +1413,7 @@ EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetBiomeAt(X, Z); @@ -1434,7 +1434,7 @@ bool cChunkMap::SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome) cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->SetBiomeAt(X, Z, a_Biome); @@ -1467,7 +1467,7 @@ bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMC { int MinRelZ = (z == MinChunkZ) ? MinZ : 0; int MaxRelZ = (z == MaxChunkZ) ? MaxZ : cChunkDef::Width - 1; - cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z); + cChunkPtr Chunk = GetChunkNoLoad(x, z); if ((Chunk != NULL) && Chunk->IsValid()) { Chunk->SetAreaBiome(MinRelX, MaxRelX, MinRelZ, MaxRelZ, a_Biome); @@ -1491,7 +1491,7 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) cCSLock Lock(m_CSLayers); for (sSetBlockVector::iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr) { - cChunkPtr Chunk = GetChunk(itr->ChunkX, ZERO_CHUNK_Y, itr->ChunkZ); + cChunkPtr Chunk = GetChunk(itr->ChunkX, itr->ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { if (!a_ContinueOnFailure) @@ -1519,7 +1519,7 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) { cCSLock Lock(m_CSLayers); - cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr DestChunk = GetChunk( ChunkX, ChunkZ); if ((DestChunk == NULL) || !DestChunk->IsValid()) { return false; @@ -1542,7 +1542,7 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != NULL) && (Chunk->IsValid())) { Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle()); @@ -1556,12 +1556,12 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, ZERO_CHUNK_Y, a_ChunkZ1); + cChunkPtr Chunk1 = GetChunkNoGen(a_ChunkX1, a_ChunkZ1); if (Chunk1 == NULL) { return; } - cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, ZERO_CHUNK_Y, a_ChunkZ2); + cChunkPtr Chunk2 = GetChunkNoGen(a_ChunkX2, a_ChunkZ2); if (Chunk2 == NULL) { return; @@ -1623,7 +1623,7 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return false; @@ -1638,7 +1638,7 @@ bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Cli void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return; @@ -1667,7 +1667,7 @@ void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) void cChunkMap::AddEntity(cEntity * a_Entity) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if ( (Chunk == NULL) || // Chunk not present at all (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953) @@ -1688,7 +1688,7 @@ void cChunkMap::AddEntity(cEntity * a_Entity) void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if ( (Chunk == NULL) || // Chunk not present at all (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953) @@ -1729,7 +1729,7 @@ bool cChunkMap::HasEntity(int a_UniqueID) void cChunkMap::RemoveEntity(cEntity * a_Entity) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); // Even if a chunk is not valid, it may still contain entities such as players; make sure to remove them (#1190) if (Chunk == NULL) @@ -1763,7 +1763,7 @@ bool cChunkMap::ForEachEntity(cEntityCallback & a_Callback) bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2011,7 +2011,7 @@ bool cChunkMap::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback) bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2026,7 +2026,7 @@ bool cChunkMap::ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEnti bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2041,7 +2041,7 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2056,7 +2056,7 @@ bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCa bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2071,7 +2071,7 @@ bool cChunkMap::ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallba bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2086,7 +2086,7 @@ bool cChunkMap::ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpens bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2104,7 +2104,7 @@ bool cChunkMap::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cB int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2122,7 +2122,7 @@ bool cChunkMap::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeacon int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2140,7 +2140,7 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2158,7 +2158,7 @@ bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDis int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2176,7 +2176,7 @@ bool cChunkMap::DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropp int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2194,7 +2194,7 @@ bool cChunkMap::DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cD int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2212,7 +2212,7 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2229,7 +2229,7 @@ bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNot int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2246,7 +2246,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2264,7 +2264,7 @@ bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHe int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2282,7 +2282,7 @@ bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlo int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2300,7 +2300,7 @@ bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2312,10 +2312,10 @@ bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & -void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + GetChunk(a_ChunkX, a_ChunkZ); } @@ -2323,11 +2323,11 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) /// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) -bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkZ) { { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { // Internal error @@ -2344,7 +2344,7 @@ bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) return false; } } - return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkZ); } @@ -2356,7 +2356,7 @@ void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) { for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) { - LoadChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + LoadChunk(itr->m_ChunkX, itr->m_ChunkZ); } // for itr - a_Chunks[] } @@ -2364,10 +2364,10 @@ void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) -void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkY, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { return; @@ -2384,7 +2384,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return false; @@ -2399,7 +2399,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { // Not present @@ -2415,7 +2415,7 @@ void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) bool cChunkMap::IsChunkLighted(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk == NULL) { // Not present @@ -2436,7 +2436,7 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh { for (int x = a_MinChunkX; x <= a_MaxChunkX; x++) { - cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z); + cChunkPtr Chunk = GetChunkNoLoad(x, z); if ((Chunk == NULL) || (!Chunk->IsValid())) { // Not present / not valid @@ -2478,7 +2478,7 @@ bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBl { for (int x = MinChunkX; x <= MaxChunkX; x++) { - cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z); + cChunkPtr Chunk = GetChunkNoLoad(x, z); if ((Chunk == NULL) || (!Chunk->IsValid())) { // Not present / not valid @@ -2519,7 +2519,7 @@ void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != NULL) { Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand); @@ -2536,7 +2536,7 @@ void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Nu cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != NULL) { Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); @@ -2553,7 +2553,7 @@ void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBl cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != NULL) { Chunk->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow); @@ -2570,7 +2570,7 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != NULL) { Chunk->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ); @@ -2625,7 +2625,7 @@ void cChunkMap::TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { return; @@ -2694,7 +2694,7 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) // a_BlockXYZ now contains relative coords! cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != NULL) { Chunk->QueueTickBlock(a_BlockX, a_BlockY, a_BlockZ); @@ -2708,7 +2708,7 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) void cChunkMap::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); if (Chunk != NULL) { Chunk->SetAlwaysTicked(a_AlwaysTicked); @@ -2753,7 +2753,7 @@ cChunkMap::cChunkLayer::~cChunkLayer() -cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ) +cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkZ) { // Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check @@ -2773,7 +2773,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ); cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX, a_ChunkZ - 1); cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX, a_ChunkZ + 1); - m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool); + m_Chunks[Index] = new cChunk(a_ChunkX, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool); } return m_Chunks[Index]; } @@ -2973,7 +2973,7 @@ void cChunkMap::cChunkLayer::Save(void) { if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty()) { - World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ()); + World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()); } } // for i - m_Chunks[] } @@ -3046,7 +3046,7 @@ void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) const cChunkCoordsVector & WantedChunks = a_ChunkStay.GetChunks(); for (cChunkCoordsVector::const_iterator itr = WantedChunks.begin(); itr != WantedChunks.end(); ++itr) { - cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkZ); if (Chunk == NULL) { continue; @@ -3095,7 +3095,7 @@ void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) const cChunkCoordsVector & Chunks = a_ChunkStay.GetChunks(); for (cChunkCoordsVector::const_iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr) { - cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkZ); if (Chunk == NULL) { continue; diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 1e9a0f982..6a379e51d 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -270,16 +270,16 @@ public: bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible /** Touches the chunk, causing it to be loaded or generated */ - void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void TouchChunk(int a_ChunkX, int a_ChunkZ); /** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */ - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool LoadChunk(int a_ChunkX, int a_ChunkZ); /** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */ void LoadChunks(const cChunkCoordsList & a_Chunks); /** Marks the chunk as failed-to-load */ - void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); /** Sets the sign text. Returns true if sign text changed. */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); @@ -363,7 +363,7 @@ private: ~cChunkLayer(); /** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */ - cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ); + cChunkPtr GetChunk( int a_ChunkX, int a_ChunkZ); /** Returns the specified chunk, or NULL if not created yet */ cChunk * FindChunk(int a_ChunkX, int a_ChunkZ); @@ -456,9 +456,9 @@ private: std::auto_ptr > m_Pool; - cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid - cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate - cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate + cChunkPtr GetChunk (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid + cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate + cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkZ); // Doesn't load, doesn't generate /** Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); diff --git a/src/ChunkSender.cpp b/src/ChunkSender.cpp index ebcf0e272..95c4d03d2 100644 --- a/src/ChunkSender.cpp +++ b/src/ChunkSender.cpp @@ -81,7 +81,7 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkZ) // This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check { cCSLock Lock(m_CS); - m_ChunksReady.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); } m_evtQueue.Set(); } @@ -95,12 +95,12 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * ASSERT(a_Client != NULL); { cCSLock Lock(m_CS); - if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ, a_Client)) != m_SendChunks.end()) + if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkZ, a_Client)) != m_SendChunks.end()) { // Already queued, bail out return; } - m_SendChunks.push_back(sSendChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ, a_Client)); + m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkZ, a_Client)); } m_evtQueue.Set(); } @@ -160,7 +160,7 @@ void cChunkSender::Execute(void) m_ChunksReady.pop_front(); Lock.Unlock(); - SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL); + SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, NULL); } else { @@ -169,7 +169,7 @@ void cChunkSender::Execute(void) m_SendChunks.pop_front(); Lock.Unlock(); - SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client); + SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client); } Lock.Lock(); int RemoveCount = m_RemoveCount; @@ -186,14 +186,14 @@ void cChunkSender::Execute(void) -void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) +void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) { ASSERT(m_World != NULL); // Ask the client if it still wants the chunk: if (a_Client != NULL) { - if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ)) + if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ)) { return; } diff --git a/src/ChunkSender.h b/src/ChunkSender.h index 624a3a0bd..a0e9087a9 100644 --- a/src/ChunkSender.h +++ b/src/ChunkSender.h @@ -95,13 +95,11 @@ protected: struct sSendChunk { int m_ChunkX; - int m_ChunkY; int m_ChunkZ; cClientHandle * m_Client; - sSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client) : + sSendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) : m_ChunkX(a_ChunkX), - m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Client(a_Client) { @@ -111,7 +109,6 @@ protected: { return ( (a_Other.m_ChunkX == m_ChunkX) && - (a_Other.m_ChunkY == m_ChunkY) && (a_Other.m_ChunkZ == m_ChunkZ) && (a_Other.m_Client == m_Client) ); @@ -162,7 +159,7 @@ protected: virtual void BlockEntity (cBlockEntity * a_Entity) override; /// Sends the specified chunk to a_Client, or to all chunk clients if a_Client == NULL - void SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client); + void SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); } ; diff --git a/src/ChunkStay.cpp b/src/ChunkStay.cpp index b5002a63d..38aa89a37 100644 --- a/src/ChunkStay.cpp +++ b/src/ChunkStay.cpp @@ -51,7 +51,7 @@ void cChunkStay::Add(int a_ChunkX, int a_ChunkZ) return; } } // for itr - Chunks[] - m_Chunks.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8aa883144..18c1a32ef 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -472,13 +472,13 @@ void cClientHandle::StreamChunks(void) // For each distance touch chunks in a hollow square centered around current position: for (int i = -d; i <= d; ++i) { - World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i); - World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i); + World->TouchChunk(ChunkPosX + d, ChunkPosZ + i); + World->TouchChunk(ChunkPosX - d, ChunkPosZ + i); } // for i for (int i = -d + 1; i < d; ++i) { - World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d); - World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d); + World->TouchChunk(ChunkPosX + i, ChunkPosZ + d); + World->TouchChunk(ChunkPosX + i, ChunkPosZ - d); } // for i } // for d } @@ -501,8 +501,8 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ) { { cCSLock Lock(m_CSChunkLists); - m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); - m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); } World->SendChunkTo(a_ChunkX, a_ChunkZ, this); } @@ -2733,7 +2733,7 @@ bool cClientHandle::HasPluginChannel(const AString & a_PluginChannel) -bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkZ) { if (m_State >= csDestroying) { @@ -2741,7 +2741,7 @@ bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) } cCSLock Lock(m_CSChunkLists); - return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); + return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkZ)) != m_ChunksToSend.end()); } @@ -2757,9 +2757,9 @@ void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); cCSLock Lock(m_CSChunkLists); - if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end()) + if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkZ)) == m_ChunksToSend.end()) { - m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)); + m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); } } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7ae70a07f..e98d7be99 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -209,7 +209,7 @@ public: // tolua_end /** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */ - bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool WantsSendChunk(int a_ChunkX, int a_ChunkZ); /** Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) */ void AddWantedChunk(int a_ChunkX, int a_ChunkZ); diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index a1188f984..4d0cf3192 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -99,7 +99,7 @@ void cChunkGenerator::Stop(void) -void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ) { { cCSLock Lock(m_CS); @@ -107,7 +107,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk // Check if it is already in the queue: for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ)) { // Already in the queue, bail out return; @@ -119,7 +119,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk { LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (" SIZE_T_FMT ")", a_ChunkX, a_ChunkZ, m_Queue.size()); } - m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); } m_Event.Set(); @@ -246,7 +246,7 @@ void cChunkGenerator::Execute(void) } // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set - if ((coords.m_ChunkY == 0) && m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ)) + if (m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ)) { LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); // Already generated, ignore request @@ -259,8 +259,8 @@ void cChunkGenerator::Execute(void) continue; } - LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); - DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ); + LOGD("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ); + DoGenerate(coords.m_ChunkX, coords.m_ChunkZ); NumChunksGenerated++; } // while (!bStop) @@ -269,7 +269,7 @@ void cChunkGenerator::Execute(void) -void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ) { ASSERT(m_PluginInterface != NULL); ASSERT(m_ChunkSink != NULL); diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index 88d71f3f9..17ca8adce 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -116,7 +116,7 @@ public: void Stop(void); /// Queues the chunk for generation; removes duplicate requests - void QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ); /// Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); @@ -154,7 +154,7 @@ private: // cIsThread override: virtual void Execute(void) override; - void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void DoGenerate(int a_ChunkX, int a_ChunkZ); }; diff --git a/src/World.cpp b/src/World.cpp index 69d1217f1..eba3a8357 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -442,7 +442,7 @@ void cWorld::InitializeSpawn(void) { for (int z = 0; z < ViewDist; z++) { - m_ChunkMap->TouchChunk(x + ChunkX-(ViewDist - 1) / 2, ZERO_CHUNK_Y, z + ChunkZ-(ViewDist - 1) / 2); // Queue the chunk in the generator / loader + m_ChunkMap->TouchChunk(x + ChunkX-(ViewDist - 1) / 2, z + ChunkZ-(ViewDist - 1) / 2); // Queue the chunk in the generator / loader } } @@ -2421,7 +2421,7 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) // Save the chunk right after generating, so that we don't have to generate it again on next run if (a_SetChunkData.ShouldMarkDirty()) { - m_Storage.QueueSaveChunk(ChunkX, 0, ChunkZ); + m_Storage.QueueSaveChunk(ChunkX, ChunkZ); } } @@ -2766,18 +2766,18 @@ void cWorld::RemoveClientFromChunkSender(cClientHandle * a_Client) -void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cWorld::TouchChunk(int a_ChunkX, int a_ChunkZ) { - m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkZ); } -bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkZ) { - return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ); + return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkZ); } @@ -2793,9 +2793,9 @@ void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks) -void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { - m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); + m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkZ); } @@ -2900,8 +2900,7 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) { m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ); - // Trick: use Y=1 to force the chunk generation even though the chunk data is already present - m_Generator.QueueGenerateChunk(a_ChunkX, 1, a_ChunkZ); + m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ); } @@ -2910,7 +2909,7 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) { - m_Generator.QueueGenerateChunk(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ); } diff --git a/src/World.h b/src/World.h index 578c9682b..50b157312 100644 --- a/src/World.h +++ b/src/World.h @@ -351,16 +351,16 @@ public: void RemoveClientFromChunkSender(cClientHandle * a_Client); /** Touches the chunk, causing it to be loaded or generated */ - void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void TouchChunk(int a_ChunkX, int a_ChunkZ); /** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */ - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool LoadChunk(int a_ChunkX, int a_ChunkZ); /** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */ void LoadChunks(const cChunkCoordsList & a_Chunks); /** Marks the chunk as failed-to-load: */ - void ChunkLoadFailed(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be NULL. Returns true if sign text changed. Same as UpdateSign() */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = NULL); // Exported in ManualBindings.cpp diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 58f9e3cab..6760186b2 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -980,7 +980,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) { // Chunk not valid - LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + LOG("cWSSCompact: Trying to save chunk [%d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } @@ -999,7 +999,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld int errorcode = CompressString(Data.data(), Data.size(), CompressedData, m_CompressionFactor); if (errorcode != Z_OK) { - LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + LOGERROR("Error %i compressing data for chunk [%d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } @@ -1010,7 +1010,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld sChunkHeader * Header = new sChunkHeader; if (Header == NULL) { - LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); + LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } Header->m_CompressedSize = (int)CompressedData.size(); diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 707e8f929..c4df8c379 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -141,9 +141,9 @@ size_t cWorldStorage::GetSaveQueueLength(void) -void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) +void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate) { - m_LoadQueue.EnqueueItem(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate)); + m_LoadQueue.EnqueueItem(sChunkLoad(a_ChunkX, a_ChunkZ, a_Generate)); m_Event.Set(); } @@ -151,9 +151,9 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, boo -void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkZ) { - m_SaveQueue.EnqueueItemIfNotPresent(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + m_SaveQueue.EnqueueItemIfNotPresent(cChunkCoords(a_ChunkX, a_ChunkZ)); m_Event.Set(); } @@ -161,9 +161,9 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkZ) { - m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, true)); + m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkZ, true)); } @@ -242,19 +242,19 @@ void cWorldStorage::Execute(void) bool cWorldStorage::LoadOneChunk(void) { - sChunkLoad ToLoad(0, 0, 0, false); + sChunkLoad ToLoad(0, 0, false); bool ShouldLoad = m_LoadQueue.TryDequeueItem(ToLoad); - if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ)) + if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ)) { if (ToLoad.m_Generate) { // The chunk couldn't be loaded, generate it: - m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ); } else { // TODO: Notify the world that the load has failed: - // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ); + // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkZ); } } return ShouldLoad; @@ -266,7 +266,7 @@ bool cWorldStorage::LoadOneChunk(void) bool cWorldStorage::SaveOneChunk(void) { - cChunkCoords ToSave(0, 0, 0); + cChunkCoords ToSave(0, 0); bool ShouldSave = m_SaveQueue.TryDequeueItem(ToSave); if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) { @@ -283,7 +283,7 @@ bool cWorldStorage::SaveOneChunk(void) -bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { if (m_World->IsChunkValid(a_ChunkX, a_ChunkZ)) { @@ -291,7 +291,7 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) return true; } - cChunkCoords Coords(a_ChunkX, a_ChunkY, a_ChunkZ); + cChunkCoords Coords(a_ChunkX, a_ChunkZ); // First try the schema that is used for saving if (m_SaveSchema->LoadChunk(Coords)) @@ -309,7 +309,7 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) } // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): - m_World->ChunkLoadFailed(a_ChunkX, a_ChunkY, a_ChunkZ); + m_World->ChunkLoadFailed(a_ChunkX, a_ChunkZ); return false; } diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index dd07ecb64..5f89ead53 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -64,13 +64,13 @@ public: cWorldStorage(void); ~cWorldStorage(); - void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true - void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true + void QueueSaveChunk(int a_ChunkX, int a_ChunkZ); /// Loads the chunk specified; returns true on success, false on failure - bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + bool LoadChunk(int a_ChunkX, int a_ChunkZ); - void UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); + void UnqueueLoad(int a_ChunkX, int a_ChunkZ); void UnqueueSave(const cChunkCoords & a_Chunk); bool Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor); // Hide the cIsThread's Start() method, we need to provide args @@ -87,17 +87,15 @@ protected: struct sChunkLoad { int m_ChunkX; - int m_ChunkY; int m_ChunkZ; bool m_Generate; // If true, the chunk will be generated if it cannot be loaded - sChunkLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} + sChunkLoad(int a_ChunkX, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} bool operator ==(const sChunkLoad other) const { return ( (this->m_ChunkX == other.m_ChunkX) && - (this->m_ChunkY == other.m_ChunkY) && (this->m_ChunkZ == other.m_ChunkZ) ); } -- cgit v1.2.3 From 6c3b80f04c7c2cca26efb57cc9827a7a1d20fcda Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 14:58:03 +0200 Subject: Fixed crashes and use std::swap. --- src/ClientHandle.cpp | 22 +++++++++++++++++++--- src/ClientHandle.h | 2 +- src/Item.cpp | 36 ++++++++++++++++++++---------------- src/UI/SlotArea.cpp | 9 +++------ 4 files changed, 43 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8aa883144..1dd8ff31c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2857,11 +2857,27 @@ void cClientHandle::SocketClosed(void) -void cClientHandle::HandleEnchantItem(Byte & WindowID, Byte & Enchantment) +void cClientHandle::HandleEnchantItem(Byte & a_WindowID, Byte & a_Enchantment) { - cEnchantingWindow * Window = (cEnchantingWindow*)m_Player->GetWindow(); + if (a_Enchantment > 2) + { + LOGWARNING("%s attempt to crash the server with invalid enchanting selection!", GetUsername().c_str()); + Kick("Invalid enchanting!"); + return; + } + + if ( + (m_Player->GetWindow() == NULL) || + (m_Player->GetWindow()->GetWindowID() != a_WindowID) || + (m_Player->GetWindow()->GetWindowType() != cWindow::wtEnchantment) + ) + { + return; + } + + cEnchantingWindow * Window = (cEnchantingWindow*) m_Player->GetWindow(); cItem Item = *Window->m_SlotArea->GetSlot(0, *m_Player); - int BaseEnchantmentLevel = Window->GetPropertyValue(Enchantment); + int BaseEnchantmentLevel = Window->GetPropertyValue(a_Enchantment); if (Item.EnchantByXPLevels(BaseEnchantmentLevel)) { diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7ae70a07f..24031119d 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -269,7 +269,7 @@ public: void RemoveFromWorld(void); /** Called when the player will enchant a Item */ - void HandleEnchantItem(Byte & WindowID, Byte & Enchantment); + void HandleEnchantItem(Byte & a_WindowID, Byte & a_Enchantment); private: diff --git a/src/Item.cpp b/src/Item.cpp index a5117c271..4d29318e6 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -291,73 +291,77 @@ int cItem::GetEnchantability() bool cItem::EnchantByXPLevels(int a_NumXPLevels) { - if (!cItem::IsEnchantable(m_ItemType) && (m_ItemType != E_ITEM_BOOK)) + if (!cItem::IsEnchantable(m_ItemType)) { return false; } int Enchantability = GetEnchantability(); + if (Enchantability == 0) + { + return false; + } cFastRandom Random; int ModifiedEnchantmentLevel = a_NumXPLevels + (int)Random.NextFloat((float)Enchantability / 4) + (int)Random.NextFloat((float)Enchantability / 4) + 1; float RandomBonus = 1.0F + (Random.NextFloat(1) + Random.NextFloat(1) - 1.0F) * 0.15F; int FinalEnchantmentLevel = (int)(ModifiedEnchantmentLevel * RandomBonus + 0.5F); - cWeightedEnchantments enchantments; - cEnchantments::AddItemEnchantmentWeights(enchantments, m_ItemType, FinalEnchantmentLevel); + cWeightedEnchantments Enchantments; + cEnchantments::AddItemEnchantmentWeights(Enchantments, m_ItemType, FinalEnchantmentLevel); if (m_ItemType == E_ITEM_BOOK) { m_ItemType = E_ITEM_ENCHANTED_BOOK; } - cEnchantments Enchantment1 = cEnchantments::GetRandomEnchantmentFromVector(enchantments); + cEnchantments Enchantment1 = cEnchantments::GetRandomEnchantmentFromVector(Enchantments); m_Enchantments.AddFromString(Enchantment1.ToString()); - cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment1); + cEnchantments::RemoveEnchantmentWeightFromVector(Enchantments, Enchantment1); // Checking for conflicting enchantments - cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment1); + cEnchantments::CheckEnchantmentConflictsFromVector(Enchantments, Enchantment1); float NewEnchantmentLevel = (float)a_NumXPLevels; // Next Enchantment (Second) NewEnchantmentLevel = NewEnchantmentLevel / 2; float SecondEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100; - if (enchantments.empty() || (Random.NextFloat(100) > SecondEnchantmentChance)) + if (Enchantments.empty() || (Random.NextFloat(100) > SecondEnchantmentChance)) { return true; } - cEnchantments Enchantment2 = cEnchantments::GetRandomEnchantmentFromVector(enchantments); + cEnchantments Enchantment2 = cEnchantments::GetRandomEnchantmentFromVector(Enchantments); m_Enchantments.AddFromString(Enchantment2.ToString()); - cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment2); + cEnchantments::RemoveEnchantmentWeightFromVector(Enchantments, Enchantment2); // Checking for conflicting enchantments - cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment2); + cEnchantments::CheckEnchantmentConflictsFromVector(Enchantments, Enchantment2); // Next Enchantment (Third) NewEnchantmentLevel = NewEnchantmentLevel / 2; float ThirdEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100; - if (enchantments.empty() || (Random.NextFloat(100) > ThirdEnchantmentChance)) + if (Enchantments.empty() || (Random.NextFloat(100) > ThirdEnchantmentChance)) { return true; } - cEnchantments Enchantment3 = cEnchantments::GetRandomEnchantmentFromVector(enchantments); + cEnchantments Enchantment3 = cEnchantments::GetRandomEnchantmentFromVector(Enchantments); m_Enchantments.AddFromString(Enchantment3.ToString()); - cEnchantments::RemoveEnchantmentWeightFromVector(enchantments, Enchantment3); + cEnchantments::RemoveEnchantmentWeightFromVector(Enchantments, Enchantment3); // Checking for conflicting enchantments - cEnchantments::CheckEnchantmentConflictsFromVector(enchantments, Enchantment3); + cEnchantments::CheckEnchantmentConflictsFromVector(Enchantments, Enchantment3); // Next Enchantment (Fourth) NewEnchantmentLevel = NewEnchantmentLevel / 2; float FourthEnchantmentChance = (NewEnchantmentLevel + 1) / 50 * 100; - if (enchantments.empty() || (Random.NextFloat(100) > FourthEnchantmentChance)) + if (Enchantments.empty() || (Random.NextFloat(100) > FourthEnchantmentChance)) { return true; } - cEnchantments Enchantment4 = cEnchantments::GetRandomEnchantmentFromVector(enchantments); + cEnchantments Enchantment4 = cEnchantments::GetRandomEnchantmentFromVector(Enchantments); m_Enchantments.AddFromString(Enchantment4.ToString()); return true; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 74173d087..88af257a0 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1423,7 +1423,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio } case caDblClick: { - // DblClicked(a_Player, a_SlotNum); + DblClicked(a_Player, a_SlotNum); return; } case caMiddleClick: @@ -1470,8 +1470,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio { if (!Slot.IsEmpty()) { - DraggingItem = Slot; - Slot.Empty(); + std::swap(DraggingItem, Slot); } } else if (Slot.IsEmpty()) @@ -1487,9 +1486,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio else if ((DraggingItem.m_ItemCount == 1) && !DraggingItem.IsEqual(Slot)) { // Switch contents - cItem tmp(DraggingItem); - DraggingItem = Slot; - Slot = tmp; + std::swap(DraggingItem, Slot); } SetSlot(a_SlotNum, a_Player, Slot); -- cgit v1.2.3 From f1470fcf9f1dc907241a645614cdcd5547dc1dbd Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 15:21:38 +0200 Subject: Fixed bad values in the IsEnchantable() method. --- src/Item.cpp | 20 ++++++++++++++++---- src/Item.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Item.cpp b/src/Item.cpp index 4d29318e6..ebdf99ca5 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -190,9 +190,16 @@ void cItem::FromJson(const Json::Value & a_Value) -bool cItem::IsEnchantable(short a_ItemType) +bool cItem::IsEnchantable(short a_ItemType, bool a_WithBook) { - if (ItemCategory::IsTool(a_ItemType) || ItemCategory::IsArmor(a_ItemType)) + if ( + ItemCategory::IsAxe(a_ItemType) || + ItemCategory::IsSword(a_ItemType) || + ItemCategory::IsShovel(a_ItemType) || + ItemCategory::IsPickaxe(a_ItemType) || + (a_WithBook && ItemCategory::IsHoe(a_ItemType)) || + ItemCategory::IsArmor(a_ItemType) + ) { return true; } @@ -201,12 +208,17 @@ bool cItem::IsEnchantable(short a_ItemType) { case E_ITEM_BOOK: case E_ITEM_BOW: - case E_ITEM_CARROT_ON_STICK: case E_ITEM_FISHING_ROD: - case E_ITEM_SHEARS: { return true; } + + case E_ITEM_CARROT_ON_STICK: + case E_ITEM_SHEARS: + case E_ITEM_FLINT_AND_STEEL: + { + return a_WithBook; + } } return false; diff --git a/src/Item.h b/src/Item.h index d8b9e78a0..61011d861 100644 --- a/src/Item.h +++ b/src/Item.h @@ -184,7 +184,7 @@ public: void FromJson(const Json::Value & a_Value); /** Returns true if the specified item type is enchantable (as per 1.2.5 protocol requirements) */ - static bool IsEnchantable(short a_ItemType); // tolua_export + static bool IsEnchantable(short a_ItemType, bool a_WithBook = false); // tolua_export /** Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0 */ int GetEnchantability(); // tolua_export -- cgit v1.2.3 From c0c4ac5236779af648fd64d32eb7075553e4a88a Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 15:21:50 +0200 Subject: Added comments. --- src/UI/SlotArea.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 88af257a0..b4facb2d3 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1468,6 +1468,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio if (DraggingItem.IsEmpty()) { + // DraggingItem is empty -> Switch draggingitem and slot if (!Slot.IsEmpty()) { std::swap(DraggingItem, Slot); @@ -1475,6 +1476,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio } else if (Slot.IsEmpty()) { + // DraggingItem isn't empty and slot is empty -> Set one dragging item in the slot Slot = DraggingItem.CopyOne(); DraggingItem.m_ItemCount -= 1; @@ -1485,7 +1487,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio } else if ((DraggingItem.m_ItemCount == 1) && !DraggingItem.IsEqual(Slot)) { - // Switch contents + // DraggingItem and slot aren't empty -> Switch items std::swap(DraggingItem, Slot); } -- cgit v1.2.3 From 49ac6fadfc441e1de1a0127ff45996ac3abae150 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:44:36 +0300 Subject: Fixed spaces after "template" keyword. --- src/Bindings/ManualBindings.cpp | 12 ++++++------ src/Blocks/ClearMetaOnDrop.h | 2 +- src/Blocks/MetaRotator.h | 10 +++++----- src/OSSupport/Queue.h | 2 +- src/StringUtils.h | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 6b40cece8..23651b0e1 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -301,11 +301,11 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(const AString &, cItemCallback &) - > +> static int tolua_DoWith(lua_State* tolua_S) { int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ @@ -395,7 +395,7 @@ static int tolua_DoWith(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, cItemCallback &) @@ -485,7 +485,7 @@ static int tolua_DoWithID(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, int, int, cItemCallback &) @@ -580,7 +580,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, int, cItemCallback &) @@ -676,7 +676,7 @@ static int tolua_ForEachInChunk(lua_State * tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(cItemCallback &) diff --git a/src/Blocks/ClearMetaOnDrop.h b/src/Blocks/ClearMetaOnDrop.h index f2afbc6ea..aa4f23848 100644 --- a/src/Blocks/ClearMetaOnDrop.h +++ b/src/Blocks/ClearMetaOnDrop.h @@ -7,7 +7,7 @@ // For example to use in class Foo which should inherit Bar use // class Foo : public cClearMetaOnDrop; -template +template class cClearMetaOnDrop : public Base { public: diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h index 599aa7ef9..4c268077a 100644 --- a/src/Blocks/MetaRotator.h +++ b/src/Blocks/MetaRotator.h @@ -20,7 +20,7 @@ Usage: Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state. */ -template +template class cMetaRotator : public Base { public: @@ -41,7 +41,7 @@ public: -template +template NIBBLETYPE cMetaRotator::MetaRotateCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -63,7 +63,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaRotateCCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -85,7 +85,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaMirrorXY(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -102,7 +102,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaMirrorYZ(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h index bf4d7f004..8d096fe29 100644 --- a/src/OSSupport/Queue.h +++ b/src/OSSupport/Queue.h @@ -20,7 +20,7 @@ cQueueFuncs and is used as the default behavior. */ /// This empty struct allows for the callback functions to be inlined -template +template struct cQueueFuncs { public: diff --git a/src/StringUtils.h b/src/StringUtils.h index a78f8b0bf..7699a18bd 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -101,7 +101,7 @@ extern int GetBEInt(const char * a_Mem); extern void SetBEInt(char * a_Mem, Int32 a_Value); /// Parses any integer type. Checks bounds and returns errors out of band. -template +template bool StringToInteger(const AString& a_str, T& a_Num) { size_t i = 0; -- cgit v1.2.3 From 9b68ff2656d5e662d33c670ee5fa20dd12b8264f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:53:26 +0300 Subject: CheckBasicStyle: Added checking for the "template" keyword. --- src/CheckBasicStyle.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index bf81a7cd5..b244b1fbc 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -108,7 +108,7 @@ local g_ViolationPatterns = -- Check that all commas have spaces after them and not in front of them: {" ,", "Extra space before a \",\""}, - {",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting + {",[^%s\"%%\']", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting -- Check that opening braces are not at the end of a code line: {"[^%s].-{\n?$", "Brace should be on a separate line"}, @@ -119,6 +119,7 @@ local g_ViolationPatterns = {"while%(", "Needs a space after \"while\""}, {"switch%(", "Needs a space after \"switch\""}, {"catch%(", "Needs a space after \"catch\""}, + {"template<", "Needs a space after \"template\""}, -- No space after keyword's parenthesis: {"[^%a#]if %( ", "Remove the space after \"(\""}, -- cgit v1.2.3 From 271c8c0d3246749087f9772df31896d93f2cb9f3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:58:48 +0300 Subject: More template keyword fixes. --- src/BlockArea.cpp | 18 +++++++++--------- src/BlockArea.h | 2 +- src/Defines.h | 2 +- src/LinearUpscale.h | 6 +++--- src/StringUtils.h | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 90f7ca6c9..ba55528b8 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -28,7 +28,7 @@ typedef void (CombinatorFunc)(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE // This wild construct allows us to pass a function argument and still have it inlined by the compiler :) /// Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinator function -template +template void InternalMergeBlocks( BLOCKTYPE * a_DstTypes, const BLOCKTYPE * a_SrcTypes, NIBBLETYPE * a_DstMetas, const NIBBLETYPE * a_SrcMetas, @@ -74,7 +74,7 @@ void InternalMergeBlocks( /// Combinator used for cBlockArea::msOverwrite merging -template +template void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { a_DstType = a_SrcType; @@ -89,7 +89,7 @@ void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE /// Combinator used for cBlockArea::msFillAir merging -template +template void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_DstType == E_BLOCK_AIR) @@ -108,7 +108,7 @@ void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY /// Combinator used for cBlockArea::msImprint merging -template +template void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_SrcType != E_BLOCK_AIR) @@ -127,7 +127,7 @@ void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY /// Combinator used for cBlockArea::msLake merging -template +template void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge is the NOP block @@ -201,7 +201,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE /** Combinator used for cBlockArea::msSpongePrint merging */ -template +template void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge overwrites nothing, everything else overwrites anything @@ -220,7 +220,7 @@ void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB /** Combinator used for cBlockArea::msDifference merging */ -template +template void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta))) @@ -246,7 +246,7 @@ void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBL /** Combinator used for cBlockArea::msMask merging */ -template +template void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // If the blocks are the same, keep the dest; otherwise replace with air @@ -2121,7 +2121,7 @@ void cBlockArea::RelSetData( -template +template void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas) { // Block types are compulsory, block metas are voluntary diff --git a/src/BlockArea.h b/src/BlockArea.h index a95ba7788..86f7c4f2d 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -362,7 +362,7 @@ protected: NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight ); - template + template void MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas); // tolua_begin } ; diff --git a/src/Defines.h b/src/Defines.h index 0981077c4..78c58034e 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -528,7 +528,7 @@ inline float GetSpecialSignf( float a_Val) -template inline T Diff(T a_Val1, T a_Val2) +template inline T Diff(T a_Val1, T a_Val2) { return std::abs(a_Val1 - a_Val2); } diff --git a/src/LinearUpscale.h b/src/LinearUpscale.h index 0b04408cf..a49f4bdf9 100644 --- a/src/LinearUpscale.h +++ b/src/LinearUpscale.h @@ -31,7 +31,7 @@ Linearly interpolates values in the array between the equidistant anchor points Works in-place (input is already present at the correct output coords) Uses templates to make it possible for the compiler to further optimizer the loops */ -template< +template < int SizeX, int SizeY, // Dimensions of the array int AnchorStepX, int AnchorStepY, typename TYPE @@ -83,7 +83,7 @@ void LinearUpscale2DArrayInPlace(TYPE * a_Array) Linearly interpolates values in the array between the equidistant anchor points (upscales). Works on two arrays, input is packed and output is to be completely constructed. */ -template void LinearUpscale2DArray( +template void LinearUpscale2DArray( TYPE * a_Src, ///< Source array of size a_SrcSizeX x a_SrcSizeY int a_SrcSizeX, int a_SrcSizeY, ///< Dimensions of the src array TYPE * a_Dst, ///< Dest array, of size (a_SrcSizeX * a_UpscaleX + 1) x (a_SrcSizeY * a_UpscaleY + 1) @@ -153,7 +153,7 @@ template void LinearUpscale2DArray( Linearly interpolates values in the array between the equidistant anchor points (upscales). Works on two arrays, input is packed and output is to be completely constructed. */ -template void LinearUpscale3DArray( +template void LinearUpscale3DArray( TYPE * a_Src, ///< Source array of size a_SrcSizeX x a_SrcSizeY x a_SrcSizeZ int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ, ///< Dimensions of the src array TYPE * a_Dst, ///< Dest array, of size (a_SrcSizeX * a_UpscaleX + 1) x (a_SrcSizeY * a_UpscaleY + 1) x (a_SrcSizeZ * a_UpscaleZ + 1) diff --git a/src/StringUtils.h b/src/StringUtils.h index a63d852ee..4a4c267c7 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -117,7 +117,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) } if (positive) { - for(size_t size = a_str.size(); i < size; i++) + for (size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { @@ -138,7 +138,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) } else { - for(size_t size = a_str.size(); i < size; i++) + for (size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { -- cgit v1.2.3 From d74e49ddc00095589cfefb29ceb23da13f3e5f0a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 17:01:59 +0300 Subject: Final template keyword style fix. --- src/AllocationPool.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 3c9dbe8c9..61431a548 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -3,7 +3,7 @@ #include -template +template class cAllocationPool { public: @@ -34,7 +34,7 @@ public: /** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/ -template +template class cListAllocationPool : public cAllocationPool { public: -- cgit v1.2.3 From 1c136a60478811dabfb54e89a27fb1229d0d1b49 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 17:04:26 +0300 Subject: Fixed a typo. --- src/Entities/Minecart.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f43c4d163..21c58fdba 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -906,7 +906,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - // Moving +X -T + // Moving +X -Z // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); -- cgit v1.2.3 From 4ff34b9f10368587b7d7ade58977fb8ec7692d73 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 18:18:21 +0200 Subject: APIDump: Added missing cItem things. --- src/Item.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Item.h b/src/Item.h index 61011d861..316928b9e 100644 --- a/src/Item.h +++ b/src/Item.h @@ -183,7 +183,7 @@ public: /** Loads the item data from JSON representation */ void FromJson(const Json::Value & a_Value); - /** Returns true if the specified item type is enchantable (as per 1.2.5 protocol requirements) */ + /** Returns true if the specified item type is enchantable. */ static bool IsEnchantable(short a_ItemType, bool a_WithBook = false); // tolua_export /** Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0 */ -- cgit v1.2.3 From eaf33e22cf65178d94aafab3df5d8a9f67581529 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 18:57:56 +0200 Subject: Fixed anvil placing. --- src/Blocks/BlockAnvil.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 5c4661c11..376bf86a3 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -40,14 +40,15 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved + NIBBLETYPE Meta = a_Player->GetEquippedItem().m_ItemDamage; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; + switch (Direction) { - case 0: a_BlockMeta = 0x2 | HighBits; break; - case 1: a_BlockMeta = 0x3 | HighBits; break; - case 2: a_BlockMeta = 0x0 | HighBits; break; - case 3: a_BlockMeta = 0x1 | HighBits; break; + case 0: a_BlockMeta = 0x2 | Meta << 2; break; + case 1: a_BlockMeta = 0x3 | Meta << 2; break; + case 2: a_BlockMeta = 0x0 | Meta << 2; break; + case 3: a_BlockMeta = 0x1 | Meta << 2; break; default: { return false; -- cgit v1.2.3 From 4470ebffd72a091cddc46022bb3f5ed378651584 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 20:49:34 +0200 Subject: Fire can be destroyed with the sword in creative-mode --- src/ClientHandle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8aa883144..f9c6a664c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1059,7 +1059,8 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc if ( m_Player->IsGameModeCreative() && - ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) + ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) && + (m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_FIRE) ) { // Players can't destroy blocks with a Sword in the hand. -- cgit v1.2.3 From 240ec9b4bdd70f29aea3340f8f684818022122fd Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 23:02:20 +0200 Subject: Added speed entity effect. --- src/ClientHandle.cpp | 2 +- src/Entities/EntityEffect.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/Entities/EntityEffect.h | 4 ++++ 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f9c6a664c..5ad9dc644 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1063,7 +1063,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc (m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_FIRE) ) { - // Players can't destroy blocks with a Sword in the hand. + // Players can't destroy blocks with a sword in the hand. return; } diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 3e28392f4..58b76b21b 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -232,6 +232,47 @@ void cEntityEffect::OnTick(cPawn & a_Target) +//////////////////////////////////////////////////////////////////////////////// +// cEntityEffectSpeed: + +void cEntityEffectSpeed::OnActivate(cPawn & a_Target) +{ + // TODO: Add SetMormalMaxSpeed to cMonster + + if (!a_Target.IsPlayer()) + { + return; + } + cPlayer * Player = (cPlayer*) &a_Target; + + Player->SetNormalMaxSpeed(1.0 + 0.2 * m_Intensity); + Player->SetSprintingMaxSpeed(1.3 + 0.26 * m_Intensity); + Player->SetFlyingMaxSpeed(1.0 + 0.2 * m_Intensity); +} + + + + + +void cEntityEffectSpeed::OnDeactivate(cPawn & a_Target) +{ + // TODO: Add SetMormalMaxSpeed to cMonster + + if (!a_Target.IsPlayer()) + { + return; + } + cPlayer * Player = (cPlayer*) &a_Target; + + Player->SetNormalMaxSpeed(1.0); + Player->SetSprintingMaxSpeed(1.3); + Player->SetFlyingMaxSpeed(1.0); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cEntityEffectInstantHealth: diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h index 47c298f57..e123a7f77 100644 --- a/src/Entities/EntityEffect.h +++ b/src/Entities/EntityEffect.h @@ -137,6 +137,10 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } + + virtual void OnActivate(cPawn & a_Target) override; + + virtual void OnDeactivate(cPawn & a_Target) override; }; -- cgit v1.2.3 From c4d7f7996b0dcd784f5e1ccc8553b062c3ac96b6 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Fri, 29 Aug 2014 00:42:33 +0200 Subject: Hotfixed recipe.txt loading. --- src/CraftingRecipes.cpp | 7 +++++-- src/StringUtils.h | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 2d80ecaf8..223184c64 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -1,4 +1,4 @@ - + // CraftingRecipes.cpp // Interfaces to the cCraftingRecipes class representing the storage of crafting recipes @@ -366,7 +366,10 @@ void cCraftingRecipes::ClearRecipes(void) void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) { - AStringVector Sides = StringSplit(a_RecipeLine, "="); + AString RecipeLine(a_RecipeLine); + RecipeLine.erase(std::remove(RecipeLine.begin(), RecipeLine.end(), ' '), RecipeLine.end()); + + AStringVector Sides = StringSplit(RecipeLine, "="); if (Sides.size() != 2) { LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); diff --git a/src/StringUtils.h b/src/StringUtils.h index 4a4c267c7..c48ca6051 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -119,7 +119,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) { for (size_t size = a_str.size(); i < size; i++) { - if ((a_str[i] <= '0') || (a_str[i] >= '9')) + if ((a_str[i] < '0') || (a_str[i] > '9')) { return false; } @@ -140,7 +140,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) { for (size_t size = a_str.size(); i < size; i++) { - if ((a_str[i] <= '0') || (a_str[i] >= '9')) + if ((a_str[i] < '0') || (a_str[i] > '9')) { return false; } -- cgit v1.2.3 From 42570cbeef6a3634f56c54008277c395edaa041e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 11:20:23 +0300 Subject: Fixed spaces. --- src/StringUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index c48ca6051..72a90a8c2 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -101,7 +101,7 @@ extern void SetBEInt(char * a_Mem, Int32 a_Value); /// Parses any integer type. Checks bounds and returns errors out of band. template -bool StringToInteger(const AString& a_str, T& a_Num) +bool StringToInteger(const AString & a_str, T & a_Num) { size_t i = 0; bool positive = true; -- cgit v1.2.3 From 97c4c057e4e818562ae0a75520923196044ed55b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 11:20:33 +0300 Subject: Fixed conversion warning. --- src/Blocks/BlockAnvil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 376bf86a3..20514580e 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -40,7 +40,7 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE Meta = a_Player->GetEquippedItem().m_ItemDamage; + NIBBLETYPE Meta = (NIBBLETYPE)a_Player->GetEquippedItem().m_ItemDamage; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; switch (Direction) -- cgit v1.2.3 From d0551e2e0a98a28f31a88d489d17b408e4a7d38d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 14:58:41 +0300 Subject: VanillaFluidSimulator: Fixed an invalid Y-coord query. This was causing a spam of console messages, along with possible server crash, when liquids passed below the world: http://forum.mc-server.org/showthread.php?tid=1508&pid=15632#pid15632 --- src/Simulator/VanillaFluidSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp index 18d9b07e1..6df75eebb 100644 --- a/src/Simulator/VanillaFluidSimulator.cpp +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -98,7 +98,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int } // Check if block below is passable - if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) + if ((a_RelY > 0) && !a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) { return Cost; } -- cgit v1.2.3 From fca5a01145f78a4ae517da6c19ee61ab54574e82 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:41:50 +0100 Subject: Improved command block security --- src/BlockEntities/CommandBlockEntity.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 45f8a3e4d..fe2f5e60a 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -13,6 +13,7 @@ #include "../Root.h" #include "../Server.h" // ExecuteConsoleCommand() #include "../Chunk.h" +#include "../ChatColor.h" @@ -206,15 +207,27 @@ void cCommandBlockEntity::Execute() virtual void Out(const AString & a_Text) { // Overwrite field - m_CmdBlock->SetLastOutput(a_Text); + m_CmdBlock->SetLastOutput(cClientHandle::FormatChatPrefix(m_CmdBlock->GetWorld()->ShouldUseChatPrefixes(), "SUCCESS", cChatColor::Green, cChatColor::White) + a_Text); } } CmdBlockOutCb(this); - LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); - - cServer * Server = cRoot::Get()->GetServer(); - - Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb); + if ( // Administrator commands are not executable by command blocks + (m_Command != "stop") && + (m_Command != "restart") && + (m_Command != "kick") && + (m_Command != "ban") && + (m_Command != "ipban") + ) + { + cServer * Server = cRoot::Get()->GetServer(); + LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); + Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb); + } + else + { + SetLastOutput(cClientHandle::FormatChatPrefix(GetWorld()->ShouldUseChatPrefixes(), "FAILURE", cChatColor::Rose, cChatColor::White) + "Adminstration commands can not be executed"); + LOGD("cCommandBlockEntity: Prevented execution of administration command %s", m_Command.c_str()); + } // TODO 2014-01-18 xdot: Update the signal strength. m_Result = 0; -- cgit v1.2.3 From 114b14faad854661040a3a65c027d6b3fa818f56 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:44:01 +0100 Subject: Removed unused code --- src/Entities/ItemFrame.cpp | 1 - src/Items/ItemHandler.h | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index f0b0c8c65..0bc10ec60 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -55,7 +55,6 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI) { if (m_Item.IsEmpty()) { - SetHealth(0); super::KilledBy(a_TDI); Destroy(); return; diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index 8b554ee34..67c250a97 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -75,7 +75,7 @@ public: int FoodLevel; double Saturation; - FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) : + FoodInfo(int a_FoodLevel, double a_Saturation) : FoodLevel(a_FoodLevel), Saturation(a_Saturation) { diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index e435a1b1f..68e541eba 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -615,7 +615,6 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) { m_Writer.BeginCompound(""); AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName()); - Vector3d Pos = a_Projectile->GetPosition(); m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0); switch (a_Projectile->GetProjectileKind()) -- cgit v1.2.3 From 21ff1d81ab4e68f31874894a1f4b7feb53d210df Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:44:10 +0100 Subject: Improved explosion damage --- src/ChunkMap.cpp | 67 +++++++++++++++++++------------------------------------- src/World.cpp | 9 +++++--- 2 files changed, 28 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index dd8be0631..8ca61e2cf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1880,21 +1880,18 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { - if (!cBlockInfo::FullyOccupiesVoxel(Block)) + if ( + ((m_World->GetTNTShrapnelLevel() == slAll) && cBlockInfo::FullyOccupiesVoxel(Block)) || + ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block == E_BLOCK_SAND) || (Block == E_BLOCK_GRAVEL))) + ) { - break; + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } - else if ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) - { - break; - } - m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } area.SetBlockTypeMeta(bx + x, by + y, bz + z, E_BLOCK_AIR, 0); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; - + break; } } // switch (BlockType) } // for z @@ -1916,51 +1913,31 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ virtual bool Item(cEntity * a_Entity) override { - if (a_Entity->IsPickup()) - { - if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) - { - return false; - } - } - - Vector3d EntityPos = a_Entity->GetPosition(); - cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - - if (!m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + if (a_Entity->IsPickup() && (a_Entity->GetTicksAlive() < 20)) { + // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) return false; } - - Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - - // Work out how far we are from the edge of the TNT's explosive effect - AbsoluteEntityPos -= m_ExplosionPos; - - // All to positive - AbsoluteEntityPos.x = abs(AbsoluteEntityPos.x); - AbsoluteEntityPos.y = abs(AbsoluteEntityPos.y); - AbsoluteEntityPos.z = abs(AbsoluteEntityPos.z); - - double FinalDamage = (((1 / AbsoluteEntityPos.x) + (1 / AbsoluteEntityPos.y) + (1 / AbsoluteEntityPos.z)) * 2) * m_ExplosionSize; - - // Clip damage values - FinalDamage = Clamp(FinalDamage, 0.0, (double)a_Entity->GetMaxHealth()); + Vector3d DistanceFromExplosion = a_Entity->GetPosition() - m_ExplosionPos; + if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible { - a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); - } + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() - Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; - if (distance_explosion.SqrLength() < 4096.0) - { - distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSize * m_ExplosionSize; + if (!m_bbTNT.IsInside(bbEntity)) // If bbEntity is inside bbTNT, not vice versa! + { + return false; + } - a_Entity->AddSpeed(distance_explosion); + // Ensure that the damage dealt is inversely proportional to the distance to the TNT centre - the closer a player is, the harder they are hit + a_Entity->TakeDamage(dtExplosion, NULL, (int)((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0); } + + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() + DistanceFromExplosion.Normalize(); + DistanceFromExplosion *= m_ExplosionSize * m_ExplosionSize; + a_Entity->AddSpeed(DistanceFromExplosion); return false; } diff --git a/src/World.cpp b/src/World.cpp index d2213d1e5..c850c50d3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1188,24 +1188,26 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo return; } - // TODO: Add damage to entities and implement block hardiness + // TODO: Implement block hardiness Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); cVector3iArray BlocksAffected; m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); BroadcastSoundEffect("random.explode", (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.6f); + { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if (ch == NULL) { continue; } + Vector3d distance_explosion = (*itr)->GetPosition() - explosion_pos; if (distance_explosion.SqrLength() < 4096.0) { - double real_distance = std::max(0.004, sqrt(distance_explosion.SqrLength())); + double real_distance = std::max(0.004, distance_explosion.Length()); double power = a_ExplosionSize / real_distance; if (power <= 1) { @@ -1217,6 +1219,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo } } } + cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData); } -- cgit v1.2.3 From 618741f78e2e840552663590fd0d6eab03aa874e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 14:43:49 +0100 Subject: Added new console command with cleanup --- src/Root.cpp | 14 +++----------- src/Server.cpp | 59 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index c20cf0d21..f72f0bae3 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -462,16 +462,6 @@ void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCall void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd) { - // Some commands are built-in: - if (a_Cmd == "stop") - { - m_bStop = true; - } - else if (a_Cmd == "restart") - { - m_bRestart = true; - } - // Put the command into a queue (Alleviates FS #363): cCSLock Lock(m_CSPendingCommands); m_PendingCommands.push_back(cCommand(a_Cmd, new cLogCommandDeleteSelfOutputCallback)); @@ -483,14 +473,16 @@ void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd) void cRoot::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) { - // Some commands are built-in: + // cRoot handles stopping and restarting due to our access to controlling variables if (a_Cmd == "stop") { m_bStop = true; + return; } else if (a_Cmd == "restart") { m_bRestart = true; + return; } LOG("Executing console command: \"%s\"", a_Cmd.c_str()); diff --git a/src/Server.cpp b/src/Server.cpp index 42ad133f1..4524ece76 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -457,33 +457,34 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac return; } - // Special handling: "stop" and "restart" are built in - if ((split[0].compare("stop") == 0) || (split[0].compare("restart") == 0)) - { - return; - } + // "stop" and "restart" are handled in cRoot::ExecuteConsoleCommand, our caller, due to its access to controlling variables // "help" and "reload" are to be handled by MCS, so that they work no matter what if (split[0] == "help") { PrintHelp(split, a_Output); + a_Output.Finished(); return; } if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); cRoot::Get()->ReloadGroups(); + a_Output.Out("Plugins and groups reloaded"); + a_Output.Finished(); return; } if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); + a_Output.Out("Plugins reloaded"); + a_Output.Finished(); return; } if (split[0] == "reloadgroups") { cRoot::Get()->ReloadGroups(); - a_Output.Out("Groups reloaded!"); + a_Output.Out("Groups reloaded"); a_Output.Finished(); return; } @@ -491,31 +492,54 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac { if (split.size() > 1) { - cPluginManager::Get()->LoadPlugin(split[1]); - - return; + a_Output.Out(cPluginManager::Get()->LoadPlugin(split[1]) ? "Plugin loaded" : "Error occurred loading plugin"); } else { - a_Output.Out("No plugin given! Command: load "); - a_Output.Finished(); - return; + a_Output.Out("Usage: load "); } + a_Output.Finished(); + return; } - if (split[0] == "unload") { if (split.size() > 1) { cPluginManager::Get()->RemovePlugin(cPluginManager::Get()->GetPlugin(split[1])); - return; + a_Output.Out("Plugin unloaded"); } else { - a_Output.Out("No plugin given! Command: unload "); - a_Output.Finished(); - return; + a_Output.Out("Usage: unload "); } + a_Output.Finished(); + return; + } + if (split[0] == "destroyentities") + { + class WorldCallback : public cWorldListCallback + { + virtual bool Item(cWorld * a_World) override + { + class EntityCallback : public cEntityCallback + { + virtual bool Item(cEntity * a_Entity) override + { + if (!a_Entity->IsPlayer()) + { + a_Entity->Destroy(); + } + return false; + } + } EC; + a_World->ForEachEntity(EC); + return false; + } + } WC; + cRoot::Get()->ForEachWorld(WC); + a_Output.Out("Destroyed all entities"); + a_Output.Finished(); + return; } // There is currently no way a plugin can do these (and probably won't ever be): @@ -610,6 +634,7 @@ void cServer::BindBuiltInConsoleCommands(void) PlgMgr->BindConsoleCommand("chunkstats", NULL, " - Displays detailed chunk memory statistics"); PlgMgr->BindConsoleCommand("load ", NULL, " - Adds and enables the specified plugin"); PlgMgr->BindConsoleCommand("unload ", NULL, " - Disables the specified plugin"); + PlgMgr->BindConsoleCommand("destroyentities", NULL, " - Destroys all entities in all worlds"); #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) PlgMgr->BindConsoleCommand("dumpmem", NULL, " - Dumps all used memory blocks together with their callstacks into memdump.xml"); -- cgit v1.2.3 From 389614c9599dc6a24a0f22b0a16e8af02e4b4cca Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 15:12:45 +0100 Subject: A better hotfix for CraftingRecipies --- src/CraftingRecipes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 223184c64..ed3409207 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -367,7 +367,7 @@ void cCraftingRecipes::ClearRecipes(void) void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) { AString RecipeLine(a_RecipeLine); - RecipeLine.erase(std::remove(RecipeLine.begin(), RecipeLine.end(), ' '), RecipeLine.end()); + RecipeLine.erase(std::remove_if(RecipeLine.begin(), RecipeLine.end(), isspace), RecipeLine.end()); AStringVector Sides = StringSplit(RecipeLine, "="); if (Sides.size() != 2) -- cgit v1.2.3 From 22e3bbd0db71f9bd6d0a4306db1127f257bd24b1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 19:19:27 +0300 Subject: Rewritten block entity loading. Block entities are now loaded based on the blocktype at the coords they specify; before loading, their type ("id" NBT tag) is checked. The chunk now expects that all block entities given to it via cChunk::SetAllData() have their valid blocktype; asserts if they don't. Fixes #1354. --- src/Chunk.cpp | 10 + src/Chunk.h | 2 +- src/SetChunkData.cpp | 33 ++++ src/SetChunkData.h | 3 + src/World.cpp | 6 +- src/WorldStorage/WSSAnvil.cpp | 438 +++++++++++++++++++++++------------------- src/WorldStorage/WSSAnvil.h | 31 +-- 7 files changed, 308 insertions(+), 215 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 116c0f3a0..40ffff834 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -296,6 +296,16 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) } m_BlockEntities.clear(); std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities); + + // Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only): + #ifdef _DEBUG + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); + BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); + ASSERT(EntityBlockType == WorldBlockType); + } // for itr - m_BlockEntities + #endif // _DEBUG // Set all block entities' World variable: for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) diff --git a/src/Chunk.h b/src/Chunk.h index 72a1f6c95..e7aeff1a4 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -155,7 +155,7 @@ public: void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; - BLOCKTYPE GetBlock(Vector3i a_cords) const { return GetBlock(a_cords.x, a_cords.y, a_cords.z);} + BLOCKTYPE GetBlock(Vector3i a_RelCords) const { return GetBlock(a_RelCords.x, a_RelCords.y, a_RelCords.z);} void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index af6ad1251..97903074a 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "SetChunkData.h" +#include "BlockEntities/BlockEntity.h" @@ -116,3 +117,35 @@ void cSetChunkData::CalculateHeightMap(void) + +void cSetChunkData::RemoveInvalidBlockEntities(void) +{ + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end();) + { + BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); + BLOCKTYPE WorldBlockType = cChunkDef::GetBlock(m_BlockTypes, (*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); + if (EntityBlockType != WorldBlockType) + { + // Bad blocktype, remove the block entity: + LOGD("Block entity blocktype mismatch at {%d, %d, %d}: entity for blocktype %s(%d) in block %s(%d). Deleting the block entity.", + (*itr)->GetPosX(), (*itr)->GetPosY(), (*itr)->GetPosZ(), + ItemTypeToString(EntityBlockType).c_str(), EntityBlockType, + ItemTypeToString(WorldBlockType).c_str(), WorldBlockType + ); + cBlockEntityList::iterator itr2 = itr; + itr2++; + m_BlockEntities.erase(itr); + delete *itr; + itr = itr2; + } + else + { + // Good blocktype, keep the block entity: + ++itr; + } + } // for itr - m_BlockEntities[] +} + + + + diff --git a/src/SetChunkData.h b/src/SetChunkData.h index a2f776f6b..03e9ef4d9 100644 --- a/src/SetChunkData.h +++ b/src/SetChunkData.h @@ -92,6 +92,9 @@ public: /** Calculates the heightmap based on the contained blocktypes and marks it valid. */ void CalculateHeightMap(void); + /** Removes the block entities that don't have a proper blocktype at their corresponding coords. */ + void RemoveInvalidBlockEntities(void); + protected: int m_ChunkX; int m_ChunkZ; diff --git a/src/World.cpp b/src/World.cpp index 69d1217f1..b01e53638 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3484,14 +3484,16 @@ void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc cChunkDef::BlockNibbles BlockMetas; a_ChunkDesc.CompressBlockMetas(BlockMetas); - m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_ChunkDesc.GetBlockTypes(), BlockMetas, NULL, NULL, // We don't have lighting, chunk will be lighted when needed &a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(), a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(), true - ))); + )); + SetChunkData->RemoveInvalidBlockEntities(); + m_World->QueueSetChunkData(SetChunkData); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index a9c9ae4b5..5978e5ef8 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -396,7 +396,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT } // for y //*/ - m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, BlockTypes, MetaData, IsLightValid ? BlockLight : NULL, @@ -404,7 +404,8 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT NULL, Biomes, Entities, BlockEntities, false - ))); + )); + m_World->QueueSetChunkData(SetChunkData); return true; } @@ -581,64 +582,32 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { continue; } - int sID = a_NBT.FindChildByName(Child, "id"); - if (sID < 0) + + // Get the BlockEntity's position + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, Child, x, y, z)) { + LOGWARNING("Bad block entity, missing the coords. Will be ignored."); continue; } - if (strncmp(a_NBT.GetData(sID), "Beacon", a_NBT.GetDataLength(sID)) == 0) - { - LoadBeaconFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) - { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST); - } - else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0) - { - LoadCommandBlockFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0) - { - LoadDropperFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "FlowerPot", a_NBT.GetDataLength(sID)) == 0) - { - LoadFlowerPotFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) - { - LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child, a_BlockTypes, a_BlockMetas); - } - else if (strncmp(a_NBT.GetData(sID), "Hopper", a_NBT.GetDataLength(sID)) == 0) - { - LoadHopperFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0) - { - LoadNoteFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "RecordPlayer", a_NBT.GetDataLength(sID)) == 0) - { - LoadJukeboxFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Sign", a_NBT.GetDataLength(sID)) == 0) - { - LoadSignFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Skull", a_NBT.GetDataLength(sID)) == 0) - { - LoadMobHeadFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0) + int RelX = x, RelY = y, RelZ = z, ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); + if (RelY == 2) { - LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child); + LOGD("HERE"); } - else if (strncmp(a_NBT.GetData(sID), "TrappedChest", a_NBT.GetDataLength(sID)) == 0) + + // Load the proper BlockEntity type based on the block type: + BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); + NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ); + std::auto_ptr be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta)); + if (be.get() == NULL) { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_TRAPPED_CHEST); + continue; } - // TODO: Other block entities + + // Add the BlockEntity to the loaded data: + a_BlockEntities.push_back(be.release()); } // for Child - tag children } @@ -646,6 +615,52 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con +cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // Load the specific BlockEntity type: + switch (a_BlockType) + { + // Specific entity loaders: + case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CHEST); + case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FURNACE, a_BlockMeta); + case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta); + case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST); + case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST); + case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN); + + // Blocktypes that have block entities but don't load their contents from disk: + case E_BLOCK_ENDER_CHEST: return NULL; + } + + // All the other blocktypes should have no entities assigned to them. Report an error: + // Get the "id" tag: + int TagID = a_NBT.FindChildByName(a_Tag, "id"); + AString TypeName(""); + if (TagID >= 0) + { + TypeName.assign(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID)); + } + LOGINFO("WorldLoader(%s): Block entity mismatch: block type %s (%d), type \"%s\", at {%d, %d, %d}; the entity will be lost.", + m_World->GetName().c_str(), + ItemTypeToString(a_BlockType).c_str(), a_BlockType, TypeName.c_str(), + a_BlockX, a_BlockY, a_BlockZ + ); + return NULL; +} + + + + + bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx) { int Type = a_NBT.FindChildByName(a_TagIdx, "id"); @@ -656,7 +671,6 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ a_Item.m_ItemType = a_NBT.GetShort(Type); if (a_Item.m_ItemType < 0) { - LOGD("Encountered an item with negative type (%d). Replacing with an empty item.", a_NBT.GetShort(Type)); a_Item.Empty(); return true; } @@ -754,16 +768,46 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a -void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the given tag is a compound: + if (a_NBT.GetType(a_TagIdx) != TAG_Compound) { - return; + return false; } - std::auto_ptr Beacon(new cBeaconEntity(x, y, z, m_World)); + // Get the "id" tag: + int TagID = a_NBT.FindChildByName(a_TagIdx, "id"); + if (TagID < 0) + { + return false; + } + + // Compare the value: + if (strncmp(a_NBT.GetData(TagID), a_ExpectedType, (size_t)a_NBT.GetDataLength(TagID)) == 0) + { + return true; + } + LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\".", + a_ExpectedType, + AString(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID)).c_str() + ); + return false; +} + + + + + +cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon")) + { + return NULL; + } + + std::auto_ptr Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels"); if (CurrentLine >= 0) @@ -790,88 +834,128 @@ void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cPar LoadItemGridFromNBT(Beacon->GetContents(), a_NBT, Items); } - a_BlockEntities.push_back(Beacon.release()); + return Beacon.release(); } -void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType) +cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + // TODO: Does vanilla use "TrappedChest" or not? MCWiki says no, but previous code says yes + // Ref.: http://minecraft.gamepedia.com/Trapped_Chest + // https://github.com/mc-server/MCServer/blob/d0551e2e0a98a28f31a88d489d17b408e4a7d38d/src/WorldStorage/WSSAnvil.cpp#L637 + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Chest") && !CheckBlockEntityType(a_NBT, a_TagIdx, "TrappedChest")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this + return NULL; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } - std::auto_ptr Chest(new cChestEntity(x, y, z, m_World, a_ChestType)); + std::auto_ptr Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType)); LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Chest.release()); + return Chest.release(); } -void cWSSAnvil::LoadDispenserFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control")) { - return; + return NULL; + } + + std::auto_ptr CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command"); + if (currentLine >= 0) + { + CmdBlock->SetCommand(a_NBT.GetString(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount"); + if (currentLine >= 0) + { + CmdBlock->SetResult(a_NBT.GetInt(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput"); + if (currentLine >= 0) + { + CmdBlock->SetLastOutput(a_NBT.GetString(currentLine)); + } + + // TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it. + + return CmdBlock.release(); +} + + + + + +cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap")) + { + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this + return NULL; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this } - std::auto_ptr Dispenser(new cDispenserEntity(x, y, z, m_World)); + std::auto_ptr Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Dispenser.release()); + return Dispenser.release(); } -void cWSSAnvil::LoadDropperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this + return NULL; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this } - std::auto_ptr Dropper(new cDropperEntity(x, y, z, m_World)); + std::auto_ptr Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Dropper.release()); + return Dropper.release(); } -void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot")) { - return; + return NULL; } - std::auto_ptr FlowerPot(new cFlowerPotEntity(x, y, z, m_World)); + + std::auto_ptr FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); short ItemType = 0, ItemData = 0; int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item"); @@ -887,37 +971,28 @@ void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const c } FlowerPot->SetItem(cItem(ItemType, 1, ItemData)); - a_BlockEntities.push_back(FlowerPot.release()); + return FlowerPot.release(); } -void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas) +cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this + return NULL; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } - // Convert coords to relative: - int RelX = x; - int RelZ = z; - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(RelX, y, RelZ, ChunkX, ChunkZ); - - // Create the furnace entity, with proper BlockType and BlockMeta info: - BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, y, RelZ); - NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, y, RelZ); - std::auto_ptr Furnace(new cFurnaceEntity(x, y, z, BlockType, BlockMeta, m_World)); + std::auto_ptr Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); // Load slots: for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) @@ -954,184 +1029,147 @@ void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cPa // Restart cooking: Furnace->ContinueCooking(); - a_BlockEntities.push_back(Furnace.release()); + return Furnace.release(); } -void cWSSAnvil::LoadHopperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this + return NULL; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this } - std::auto_ptr Hopper(new cHopperEntity(x, y, z, m_World)); + std::auto_ptr Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Hopper.release()); + return Hopper.release(); } -void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer")) { - return; + return NULL; } - std::auto_ptr Jukebox(new cJukeboxEntity(x, y, z, m_World)); + + std::auto_ptr Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int Record = a_NBT.FindChildByName(a_TagIdx, "Record"); if (Record >= 0) { Jukebox->SetRecord(a_NBT.GetInt(Record)); } - a_BlockEntities.push_back(Jukebox.release()); -} - - - - - -void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - std::auto_ptr Note(new cNoteEntity(x, y, z, m_World)); - int note = a_NBT.FindChildByName(a_TagIdx, "note"); - if (note >= 0) - { - Note->SetPitch(a_NBT.GetByte(note)); - } - a_BlockEntities.push_back(Note.release()); + return Jukebox.release(); } -void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull")) { - return; + return NULL; } - std::auto_ptr Sign(new cSignEntity(E_BLOCK_SIGN_POST, x, y, z, m_World)); - int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); - if (currentLine >= 0) - { - Sign->SetLine(0, a_NBT.GetString(currentLine)); - } + std::auto_ptr MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2"); + int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType"); if (currentLine >= 0) { - Sign->SetLine(1, a_NBT.GetString(currentLine)); + MobHead->SetType(static_cast(a_NBT.GetByte(currentLine))); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot"); if (currentLine >= 0) { - Sign->SetLine(2, a_NBT.GetString(currentLine)); + MobHead->SetRotation(static_cast(a_NBT.GetByte(currentLine))); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType"); if (currentLine >= 0) { - Sign->SetLine(3, a_NBT.GetString(currentLine)); + MobHead->SetOwner(a_NBT.GetString(currentLine)); } - a_BlockEntities.push_back(Sign.release()); + return MobHead.release(); } -void cWSSAnvil::LoadMobHeadFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - std::auto_ptr MobHead(new cMobHeadEntity(x, y, z, m_World)); - - int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType"); - if (currentLine >= 0) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music")) { - MobHead->SetType(static_cast(a_NBT.GetByte(currentLine))); + return NULL; } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot"); - if (currentLine >= 0) + std::auto_ptr NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + int note = a_NBT.FindChildByName(a_TagIdx, "note"); + if (note >= 0) { - MobHead->SetRotation(static_cast(a_NBT.GetByte(currentLine))); + NoteBlock->SetPitch(a_NBT.GetByte(note)); } - - currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType"); - if (currentLine >= 0) - { - MobHead->SetOwner(a_NBT.GetString(currentLine)); - } - - a_BlockEntities.push_back(MobHead.release()); + return NoteBlock.release(); } -void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign")) { - return; + return NULL; } - std::auto_ptr CmdBlock(new cCommandBlockEntity(x, y, z, m_World)); - int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command"); + std::auto_ptr Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World)); + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); if (currentLine >= 0) { - CmdBlock->SetCommand(a_NBT.GetString(currentLine)); + Sign->SetLine(0, a_NBT.GetString(currentLine)); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2"); if (currentLine >= 0) { - CmdBlock->SetResult(a_NBT.GetInt(currentLine)); + Sign->SetLine(1, a_NBT.GetString(currentLine)); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3"); if (currentLine >= 0) { - CmdBlock->SetLastOutput(a_NBT.GetString(currentLine)); + Sign->SetLine(2, a_NBT.GetString(currentLine)); } - // TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it. + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4"); + if (currentLine >= 0) + { + Sign->SetLine(3, a_NBT.GetString(currentLine)); + } - a_BlockEntities.push_back(CmdBlock.release()); + return Sign.release(); } diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index a41268f4c..591ec6757 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -125,6 +125,10 @@ protected: /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); + /** Loads the data for a block entity from the specified NBT tag. + Returns the loaded block entity, or NULL upon failure. */ + cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + /// Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx); @@ -134,18 +138,21 @@ protected: */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); - void LoadBeaconFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType); - void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); - void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMobHeadFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */ + bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType); + + cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType); + cBlockEntity * LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType); void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength); -- cgit v1.2.3 From 75e131638616c68d126eb64abdf903a93dd7322f Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Fri, 29 Aug 2014 20:19:45 +0200 Subject: fix chunk regenerating --- src/Generating/ChunkGenerator.cpp | 8 -------- src/World.cpp | 8 ++++++++ src/World.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 4d0cf3192..a1c3d50cc 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -245,14 +245,6 @@ void cChunkGenerator::Execute(void) LastReportTick = clock(); } - // Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set - if (m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ)) - { - LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); - // Already generated, ignore request - continue; - } - if (SkipEnabled && !m_ChunkSink->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkZ)) { LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ); diff --git a/src/World.cpp b/src/World.cpp index eba3a8357..aba5bd859 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2909,7 +2909,15 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) { + if (!(m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ))) + { + LOGD("Chunk [%d, %d] already generated, skipping generation", a_ChunkX, a_ChunkZ); + // Already generated, ignore reques + } + else + { m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ); + } } diff --git a/src/World.h b/src/World.h index 50b157312..49e30694e 100644 --- a/src/World.h +++ b/src/World.h @@ -380,7 +380,7 @@ public: /** Regenerate the given chunk: */ void RegenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export - /** Generates the given chunk, if not already generated */ + /** Generates the given chunk */ void GenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export /** Queues a chunk for lighting; a_Callback is called after the chunk is lighted */ -- cgit v1.2.3 From e45a27add934dcdad8eadcea16ce647fb87fbf9d Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Fri, 29 Aug 2014 20:26:19 +0200 Subject: add comments --- src/World.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index aba5bd859..7c6a1af2f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2909,10 +2909,11 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) { + /** Add a chunk to the generation queue, if it's not already present. */ if (!(m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ))) { LOGD("Chunk [%d, %d] already generated, skipping generation", a_ChunkX, a_ChunkZ); - // Already generated, ignore reques + /** Already generated, ignore reques */ } else { -- cgit v1.2.3 From 5a6ef8b8e5887a13b252623a584ac05f0b2bd070 Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Fri, 29 Aug 2014 20:27:58 +0200 Subject: me being stupid --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 7c6a1af2f..f6fed53ee 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2913,7 +2913,7 @@ void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) if (!(m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ))) { LOGD("Chunk [%d, %d] already generated, skipping generation", a_ChunkX, a_ChunkZ); - /** Already generated, ignore reques */ + /** Already generated, ignore request */ } else { -- cgit v1.2.3 From a2bee74a13989f725e8f8ca3ffe967e157f8d77f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 23:21:58 +0300 Subject: cChunk: Fixed the Coords param. --- src/Chunk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Chunk.h b/src/Chunk.h index e7aeff1a4..e5de22e3b 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -155,7 +155,7 @@ public: void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; - BLOCKTYPE GetBlock(Vector3i a_RelCords) const { return GetBlock(a_RelCords.x, a_RelCords.y, a_RelCords.z);} + BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); } void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); -- cgit v1.2.3 From 4900645b2838b8a953fba298c5001b4e2d242931 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Sat, 30 Aug 2014 00:27:33 +0200 Subject: Added a_Digger check --- src/Blocks/BlockHandler.cpp | 59 ++++++++++++++++++++++++--------------------- src/Entities/Entity.cpp | 4 +-- 2 files changed, 33 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index c8a57906f..feb024b7f 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -433,38 +433,41 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac else { // TODO: Add a proper overridable function for this - cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; - if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) + if (a_Digger != NULL) { - switch (m_BlockType) + cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_CROPS: + switch (m_BlockType) { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - break; - }; - default: Pickups.Add(m_BlockType, 1, Meta); + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + break; + }; + default: Pickups.Add(m_BlockType, 1, Meta); + } + } + else + { + Pickups.Add(m_BlockType, 1, Meta); } - } - else - { - Pickups.Add(m_BlockType, 1, Meta); } } } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 760401cc2..10a0f8920 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -400,9 +400,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; - if (Item.m_Enchantments.GetLevel(cEnchantments::enchThorns) > ThornsLevel) ThornsLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchThorns); + ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); } - + if (ThornsLevel > 0) { int Chance = ThornsLevel * 15; -- cgit v1.2.3 From ac95173e81028856e7dac7e751c9526d0c9d4c8a Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Sat, 30 Aug 2014 00:45:05 +0200 Subject: remove orphaned comment. --- src/ChunkDef.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/ChunkDef.h b/src/ChunkDef.h index b7122efe2..111e081db 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -16,10 +16,6 @@ -/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord. -It will help us when the new chunk format comes out and we need to patch everything up for compatibility. -*/ - // Used to smoothly convert to new axis ordering. One will be removed when deemed stable. #define AXIS_ORDER_YZX 1 // Original (1.1-) #define AXIS_ORDER_XZY 2 // New (1.2+) -- cgit v1.2.3 From d7ee2245e89ce9e71f0172d5a0edf605060bcf2a Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 30 Aug 2014 12:44:54 +0200 Subject: Added SetWalkSpeed() to cMonster. --- src/Mobs/Monster.cpp | 4 ++++ src/Mobs/Monster.h | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index f7ee0b0c0..09a22cd35 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -89,6 +89,7 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_DropChanceBoots(0.085f) , m_CanPickUpLoot(true) , m_BurnsInDaylight(false) + , m_WalkSpeed(1.0) { if (!a_ConfigName.empty()) { @@ -302,6 +303,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) Distance *= 0.25f; } + // Apply walk speed: + Distance *= m_WalkSpeed; + AddSpeedX(Distance.x); AddSpeedZ(Distance.z); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index cdbd26c09..6db8435e2 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -138,6 +138,9 @@ public: /// Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; } + double GetWalkSpeed(void) const { return m_WalkSpeed; } // tolua_export + void SetWalkSpeed(double a_WalkSpeed) { m_WalkSpeed = a_WalkSpeed; } // tolua_export + // Overridables to handle ageable mobs virtual bool IsBaby (void) const { return false; } virtual bool IsTame (void) const { return false; } @@ -248,6 +251,8 @@ protected: void HandleDaylightBurning(cChunk & a_Chunk); bool m_BurnsInDaylight; + double m_WalkSpeed; + /** Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops*/ void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); -- cgit v1.2.3 From 003206b1b038f4616d5318068106573cec4d4ecd Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 30 Aug 2014 12:45:39 +0200 Subject: Added slowness effect and added entity support. --- src/Entities/EntityEffect.cpp | 77 ++++++++++++++++++++++++++++++++++--------- src/Entities/EntityEffect.h | 4 +++ 2 files changed, 65 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 58b76b21b..9cf20095d 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -237,17 +237,18 @@ void cEntityEffect::OnTick(cPawn & a_Target) void cEntityEffectSpeed::OnActivate(cPawn & a_Target) { - // TODO: Add SetMormalMaxSpeed to cMonster - - if (!a_Target.IsPlayer()) + if (a_Target.IsMob()) { - return; + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetWalkSpeed(Mob->GetWalkSpeed() + 0.2 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() + 0.2 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() + 0.26 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() + 0.2 * m_Intensity); } - cPlayer * Player = (cPlayer*) &a_Target; - - Player->SetNormalMaxSpeed(1.0 + 0.2 * m_Intensity); - Player->SetSprintingMaxSpeed(1.3 + 0.26 * m_Intensity); - Player->SetFlyingMaxSpeed(1.0 + 0.2 * m_Intensity); } @@ -256,17 +257,61 @@ void cEntityEffectSpeed::OnActivate(cPawn & a_Target) void cEntityEffectSpeed::OnDeactivate(cPawn & a_Target) { - // TODO: Add SetMormalMaxSpeed to cMonster + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetWalkSpeed(Mob->GetWalkSpeed() - 0.2 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() - 0.2 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() - 0.26 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() - 0.2 * m_Intensity); + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cEntityEffectSlowness: - if (!a_Target.IsPlayer()) +void cEntityEffectSlowness::OnActivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) { - return; + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetWalkSpeed(Mob->GetWalkSpeed() - 0.15 * m_Intensity); } - cPlayer * Player = (cPlayer*) &a_Target; + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() - 0.15 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() - 0.195 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() - 0.15 * m_Intensity); + } +} + + - Player->SetNormalMaxSpeed(1.0); - Player->SetSprintingMaxSpeed(1.3); - Player->SetFlyingMaxSpeed(1.0); + + +void cEntityEffectSlowness::OnDeactivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetWalkSpeed(Mob->GetWalkSpeed() + 0.15 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() + 0.15 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() + 0.195 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() + 0.15 * m_Intensity); + } } diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h index e123a7f77..7cf9cd3d5 100644 --- a/src/Entities/EntityEffect.h +++ b/src/Entities/EntityEffect.h @@ -156,6 +156,10 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } + + virtual void OnActivate(cPawn & a_Target) override; + + virtual void OnDeactivate(cPawn & a_Target) override; }; -- cgit v1.2.3 From 0fdb1772083d7b4b8dd71c6f084acd9d2e001eec Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 30 Aug 2014 12:46:26 +0200 Subject: Fixed potion removing in creative mode. --- src/Entities/Player.cpp | 6 ++---- src/Items/ItemGoldenApple.h | 1 + src/Items/ItemHandler.cpp | 1 + src/Items/ItemMilk.h | 8 ++++++-- src/Items/ItemPotion.h | 8 ++++++-- 5 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index b0dd40615..5e0da3298 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -627,13 +627,11 @@ void cPlayer::FinishEating(void) } ItemHandler->OnFoodEaten(m_World, this, &Item); - GetInventory().RemoveOneEquippedItem(); - // if the food is mushroom soup, return a bowl to the inventory if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP) { - cItem EmptyBowl(E_ITEM_BOWL); - GetInventory().AddItem(EmptyBowl, true, true); + GetInventory().RemoveOneEquippedItem(); + GetInventory().AddItem(cItem(E_ITEM_BOWL), true, true); } } diff --git a/src/Items/ItemGoldenApple.h b/src/Items/ItemGoldenApple.h index 02ac0202c..5f6f1de6c 100644 --- a/src/Items/ItemGoldenApple.h +++ b/src/Items/ItemGoldenApple.h @@ -36,6 +36,7 @@ public: a_Player->AddEntityEffect(cEntityEffect::effFireResistance, 6000, 0); } + a_Player->GetInventory().RemoveOneEquippedItem(); return true; } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index bceedaf69..ca0f04dcc 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -632,6 +632,7 @@ bool cItemHandler::GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_Eff bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { UNUSED(a_Item); + a_Player->GetInventory().RemoveOneEquippedItem(); FoodInfo Info = GetFoodInfo(); if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) diff --git a/src/Items/ItemMilk.h b/src/Items/ItemMilk.h index db7bc13be..c9a90865a 100644 --- a/src/Items/ItemMilk.h +++ b/src/Items/ItemMilk.h @@ -21,8 +21,12 @@ public: { UNUSED(a_Item); a_Player->ClearEntityEffects(); - a_Player->GetInventory().RemoveOneEquippedItem(); - a_Player->GetInventory().AddItem(E_ITEM_BUCKET); + + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + a_Player->GetInventory().AddItem(E_ITEM_BUCKET); + } return true; } }; diff --git a/src/Items/ItemPotion.h b/src/Items/ItemPotion.h index 24614cd8a..398ef6805 100644 --- a/src/Items/ItemPotion.h +++ b/src/Items/ItemPotion.h @@ -68,8 +68,12 @@ public: cEntityEffect::GetPotionEffectDuration(PotionDamage), cEntityEffect::GetPotionEffectIntensity(PotionDamage) ); - a_Player->GetInventory().RemoveOneEquippedItem(); - a_Player->GetInventory().AddItem(E_ITEM_GLASS_BOTTLE); + + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + a_Player->GetInventory().AddItem(E_ITEM_GLASS_BOTTLE); + } return true; } }; -- cgit v1.2.3 From 3ee3a59e75ac1e6eb9284983a05a459aab5be1fd Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 30 Aug 2014 15:06:43 +0200 Subject: Changed the IsEnchantable() comment. --- src/Item.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Item.h b/src/Item.h index 316928b9e..e7fd67b9a 100644 --- a/src/Item.h +++ b/src/Item.h @@ -183,7 +183,8 @@ public: /** Loads the item data from JSON representation */ void FromJson(const Json::Value & a_Value); - /** Returns true if the specified item type is enchantable. */ + /** Returns true if the specified item type is enchantable. + If WithBook is true, the function checks the enchantments with a book too. */ static bool IsEnchantable(short a_ItemType, bool a_WithBook = false); // tolua_export /** Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0 */ -- cgit v1.2.3 From b0a7d93ae1b3de1a6c14caf30f26682108b4a6b7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:11:09 +0200 Subject: Fixed MSVC2008 compilation. It was getting confused about which sqrt() overload to call. --- src/Entities/Minecart.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 21c58fdba..1501eea84 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -891,31 +891,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ) { // Moving -X +Z - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + if ((-GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01) { // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump! - AddSpeedX(-4 / sqrt(2)); - AddSpeedZ(4 / sqrt(2)); + AddSpeedX(-4 / sqrt(2.0)); + AddSpeedZ(4 / sqrt(2.0)); } else { // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit. - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } } - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + else if ((GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01) { // Moving +X -Z // ~ SpeedX <= 0 Immobile or not moving in the "right" direction - AddSpeedX(4 / sqrt(2)); - AddSpeedZ(-4 / sqrt(2)); + AddSpeedX(4 / sqrt(2.0)); + AddSpeedZ(-4 / sqrt(2.0)); } else { // ~ SpeedX > 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } break; } @@ -943,28 +943,28 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) if ((GetSpeedX() * 0.4) < 0.01) { // ~ SpeedX <= 0 Immobile or not moving in the "right" direction - AddSpeedX(4 / sqrt(2)); - AddSpeedZ(4 / sqrt(2)); + AddSpeedX(4 / sqrt(2.0)); + AddSpeedZ(4 / sqrt(2.0)); } else { // ~ SpeedX > 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } } else if ((-GetSpeedX() * 0.4) < 0.01) { // Moving -X -Z // ~ SpeedX >= 0 Immobile or not moving in the "right" direction - AddSpeedX(-4 / sqrt(2)); - AddSpeedZ(-4 / sqrt(2)); + AddSpeedX(-4 / sqrt(2.0)); + AddSpeedZ(-4 / sqrt(2.0)); } else { // ~ SpeedX < 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } break; } -- cgit v1.2.3 From fc7da227386a1788a8b6ddaeb5ae5b52fde107be Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:11:52 +0200 Subject: WSSAnvil: Removed leftover debugging code. --- src/WorldStorage/WSSAnvil.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 5978e5ef8..e79cc291d 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -592,10 +592,6 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con } int RelX = x, RelY = y, RelZ = z, ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); - if (RelY == 2) - { - LOGD("HERE"); - } // Load the proper BlockEntity type based on the block type: BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); -- cgit v1.2.3 From db663c7ee1737f5e03c0bce6584933123b9d58e3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:24:04 +0200 Subject: Fixed style. --- src/BlockEntities/CommandBlockEntity.cpp | 5 +++-- src/ChunkMap.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index fe2f5e60a..dd0858378 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -211,13 +211,14 @@ void cCommandBlockEntity::Execute() } } CmdBlockOutCb(this); - if ( // Administrator commands are not executable by command blocks + // Administrator commands are not executable by command blocks: + if ( (m_Command != "stop") && (m_Command != "restart") && (m_Command != "kick") && (m_Command != "ban") && (m_Command != "ipban") - ) + ) { cServer * Server = cRoot::Get()->GetServer(); LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 8ca61e2cf..a3692ef11 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1880,10 +1880,11 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { + // If the block is shrapnel-able, make a falling block entity out of it: if ( ((m_World->GetTNTShrapnelLevel() == slAll) && cBlockInfo::FullyOccupiesVoxel(Block)) || ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block == E_BLOCK_SAND) || (Block == E_BLOCK_GRAVEL))) - ) + ) { m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } @@ -1891,7 +1892,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ area.SetBlockTypeMeta(bx + x, by + y, bz + z, E_BLOCK_AIR, 0); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; + break; } } // switch (BlockType) } // for z -- cgit v1.2.3 From 365d2447d002747c0f43471e0d3bf42ea9d21363 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 00:15:48 +0100 Subject: Check range of y in HasNearLog Fixes #803 --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 972dd6232..a8aa28a0f 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -152,7 +152,7 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ) a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE); for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++) { - for (int y = a_BlockY - i; y <= a_BlockY + i; y++) + for (int y = std::max(a_BlockY - i, 0); y <= std::min(a_BlockY + i, 255); y++) { for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++) { -- cgit v1.2.3 From 6180f7df095c228530e4c0d2bfaa90fed7b11f49 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Sun, 31 Aug 2014 11:28:42 +0200 Subject: Fixed style --- src/Entities/Entity.cpp | 12 +++++------- src/Entities/Player.cpp | 3 +++ src/Entities/ProjectileEntity.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 10a0f8920..e36ed6c37 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -396,7 +396,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; @@ -428,7 +428,8 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } - if (IsPlayer()){ + if (IsPlayer()) + { double TotalEPF = 0.0; double EPFProtection = 0.00; double EPFFireProtection = 0.00; @@ -436,7 +437,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; @@ -469,7 +470,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) TotalEPF = EPFProtection + EPFFireProtection + EPFFeatherFalling + EPFBlastProtection + EPFProjectileProtection; - EPFProtection = EPFProtection / TotalEPF; EPFFireProtection = EPFFireProtection / TotalEPF; EPFFeatherFalling = EPFFeatherFalling / TotalEPF; @@ -507,8 +507,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) a_TDI.FinalDamage -= RemovedDamage; } - - + m_Health -= (short)a_TDI.FinalDamage; @@ -516,7 +515,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); - if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8b829d090..338a87ac1 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1963,6 +1963,8 @@ void cPlayer::UseEquippedItem(int a_Amount) { return; } + + // If the item has an unbreaking enchantment, give it a random chance of not breaking: cItem Item = GetEquippedItem(); int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking); if (UnbreakingLevel > 0) @@ -1983,6 +1985,7 @@ void cPlayer::UseEquippedItem(int a_Amount) return; } } + if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 58dc38702..990136a32 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -94,7 +94,7 @@ protected: */ struct CreatorData { - CreatorData(int a_UniqueID, const AString & a_Name, cEnchantments a_Enchantments) : + CreatorData(int a_UniqueID, const AString & a_Name, const cEnchantments & a_Enchantments) : m_UniqueID(a_UniqueID), m_Name(a_Name), m_Enchantments(a_Enchantments) -- cgit v1.2.3 From 7e5f22141f72fd1ad0ec7982df03f126e9c11244 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 12:59:04 +0200 Subject: WebAdmin: Added "files" folder and load the login template from login_template.html --- src/WebAdmin.cpp | 106 +++++++++++++++++++++++++++++++++++++++++++++++++------ src/WebAdmin.h | 6 ++++ 2 files changed, 102 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 23eedbd14..0646c9d1c 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -135,6 +135,20 @@ bool cWebAdmin::Start(void) m_TemplateScript.Close(); } + if (!LoadLoginTemplate()) + { + LOGWARN("Could not load WebAdmin login template \"%s\", using fallback template.", FILE_IO_PREFIX "webadmin/login_template.html"); + + // Sets the fallback template: + m_LoginTemplate = \ + "

MCServer WebAdmin

" \ + "
" \ + "
" \ + "" \ + "
" \ + "
"; + } + m_IsRunning = m_HTTPServer.Start(*this); return m_IsRunning; } @@ -159,6 +173,28 @@ void cWebAdmin::Stop(void) +bool cWebAdmin::LoadLoginTemplate(void) +{ + cFile File(FILE_IO_PREFIX "webadmin/login_template.html", cFile::fmRead); + if (!File.IsOpen()) + { + return false; + } + + AString TemplateContent; + if (File.ReadRestOfFile(TemplateContent) == -1) + { + return false; + } + + m_LoginTemplate = TemplateContent; + return true; +} + + + + + void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) { if (!a_Request.HasAuth()) @@ -298,17 +334,11 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque void cWebAdmin::HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) { UNUSED(a_Request); - static const char LoginForm[] = \ - "

MCServer WebAdmin

" \ - "
" \ - "
" \ - "" \ - "
" \ - "
"; + cHTTPResponse Resp; Resp.SetContentType("text/html"); a_Connection.Send(Resp); - a_Connection.Send(LoginForm, sizeof(LoginForm) - 1); + a_Connection.Send(m_LoginTemplate); a_Connection.FinishResponse(); } @@ -528,7 +558,64 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & } else { - // TODO: Handle other requests + AString FileURL = URL; + std::replace(FileURL.begin(), FileURL.end(), '\\', '/'); + + // Remove all backsplashes on the first place: + if (FileURL[0] == '/') + { + size_t FirstCharToRead = FileURL.find_first_not_of('/'); + if (FirstCharToRead != AString::npos) + { + FileURL = FileURL.substr(FirstCharToRead); + } + } + + // Remove all "../" strings: + ReplaceString(FileURL, "../", ""); + + bool LoadedSuccessfull = false; + AString Content = "

404 Not Found

"; + AString Path = Printf(FILE_IO_PREFIX "webadmin/files/%s", FileURL.c_str()); + if (cFile::IsFile(Path)) + { + cFile File(Path, cFile::fmRead); + AString FileContent; + if (File.IsOpen() && (File.ReadRestOfFile(FileContent) != -1)) + { + LoadedSuccessfull = true; + Content = FileContent; + } + } + + // Find content type (The currently method is very bad. We should change it later) + AString ContentType = "text/html"; + size_t LastPointPosition = Path.find_last_of('.'); + if (LoadedSuccessfull && (LastPointPosition != AString::npos) && (LastPointPosition < Path.length())) + { + const AString & FileExtension = StrToLower(Path.substr(LastPointPosition + 1)); + if (FileExtension == "png") ContentType = "image/png"; + if (FileExtension == "fif") ContentType = "image/fif"; + if (FileExtension == "gif") ContentType = "image/gif"; + if (FileExtension == "jpeg") ContentType = "image/jpeg"; + if (FileExtension == "jpg") ContentType = "image/jpeg"; + if (FileExtension == "jpe") ContentType = "image/jpeg"; + if (FileExtension == "tiff") ContentType = "image/tiff"; + if (FileExtension == "ico") ContentType = "image/ico"; + if (FileExtension == "csv") ContentType = "text/comma-separated-values"; + if (FileExtension == "css") ContentType = "text/css"; + if (FileExtension == "js") ContentType = "text/javascript"; + if (FileExtension == "txt") ContentType = "text/plain"; + if (FileExtension == "rtx") ContentType = "text/richtext"; + if (FileExtension == "xml") ContentType = "text/xml"; + } + + // Send the response: + cHTTPResponse Resp; + Resp.SetContentType(ContentType); + a_Connection.Send(Resp); + a_Connection.Send(Content); + a_Connection.FinishResponse(); } // Delete any request data assigned to the request: @@ -551,4 +638,3 @@ void cWebAdmin::cWebadminRequestData::OnBody(const char * a_Data, size_t a_Size) - diff --git a/src/WebAdmin.h b/src/WebAdmin.h index aefc1d145..a59c69096 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -116,6 +116,9 @@ public: /** Stops the HTTP server, if it was started. */ void Stop(void); + /** Loads the login template. Returns true if the loading success, false if not. */ + bool LoadLoginTemplate(void); + void AddPlugin(cWebPlugin * a_Plugin); void RemovePlugin(cWebPlugin * a_Plugin); @@ -205,6 +208,9 @@ protected: /** The Lua template script to provide templates: */ cLuaState m_TemplateScript; + /** The template who provide the login side: */ + AString m_LoginTemplate; + /** The HTTP server which provides the underlying HTTP parsing, serialization and events */ cHTTPServer m_HTTPServer; -- cgit v1.2.3 From e67bb7f431e275b5313ff412266905dc1499294a Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 15:03:23 +0200 Subject: WebAdmin: Stop webadmin if template can't load. --- src/WebAdmin.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 0646c9d1c..35a6d401c 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -131,8 +131,10 @@ bool cWebAdmin::Start(void) m_TemplateScript.RegisterAPILibs(); if (!m_TemplateScript.LoadFile(FILE_IO_PREFIX "webadmin/template.lua")) { - LOGWARN("Could not load WebAdmin template \"%s\", using default template.", FILE_IO_PREFIX "webadmin/template.lua"); + LOGERROR("Could not load WebAdmin template \"%s\". WebAdmin disabled!", FILE_IO_PREFIX "webadmin/template.lua"); m_TemplateScript.Close(); + m_HTTPServer.Stop(); + return false; } if (!LoadLoginTemplate()) -- cgit v1.2.3 From 0beed83ae9e6d8502450489edddd27171ff15b53 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 19:00:36 +0200 Subject: Rewrited furnace.txt loading. --- src/Bindings/ManualBindings.cpp | 2 +- src/BlockEntities/FurnaceEntity.h | 2 +- src/FurnaceRecipe.cpp | 241 +++++++++++++++++--------------------- src/FurnaceRecipe.h | 33 ++---- 4 files changed, 119 insertions(+), 159 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index b2c57e52d..adf10a72f 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2663,7 +2663,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) // Get the recipe for the input cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); - const cFurnaceRecipe::Recipe * Recipe = FR->GetRecipeFrom(*Input); + const cFurnaceRecipe::cRecipe * Recipe = FR->GetRecipeFrom(*Input); if (Recipe == NULL) { // There is no such furnace recipe for this input, return no value diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 4f935a74b..cf1a755e0 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -105,7 +105,7 @@ protected: NIBBLETYPE m_BlockMeta; /// The recipe for the current input slot - const cFurnaceRecipe::Recipe * m_CurrentRecipe; + const cFurnaceRecipe::cRecipe * m_CurrentRecipe; /// The item that is being smelted cItem m_LastInput; diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index ab772e97b..eb64e0a91 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -12,8 +12,8 @@ -typedef std::list< cFurnaceRecipe::Recipe > RecipeList; -typedef std::list< cFurnaceRecipe::Fuel > FuelList; +typedef std::list RecipeList; +typedef std::list FuelList; @@ -30,7 +30,7 @@ struct cFurnaceRecipe::sFurnaceRecipeState cFurnaceRecipe::cFurnaceRecipe() - : m_pState( new sFurnaceRecipeState) + : m_pState(new sFurnaceRecipeState) { ReloadRecipes(); } @@ -68,12 +68,18 @@ void cFurnaceRecipe::ReloadRecipes(void) while (std::getline(f, ParsingLine)) { LineNum++; - ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line if (ParsingLine.empty()) { continue; } + // Remove comments from the line: + size_t FirstCommentSymbol = ParsingLine.find('#'); + if ((FirstCommentSymbol != AString::npos) && (FirstCommentSymbol != 0)) + { + ParsingLine.erase(ParsingLine.begin() + FirstCommentSymbol, ParsingLine.end()); + } + switch (ParsingLine[0]) { case '#': @@ -105,157 +111,130 @@ void cFurnaceRecipe::ReloadRecipes(void) void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) { - // Fuel - int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; - AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) - - if ( - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "=", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "0123456789", a_Line, a_LineNum, IBurnTime, true) // Read item burn time - last value - ) + AString Line(a_Line); + Line.erase(Line.begin()); // Remove the beginning "!" + Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); + + cItem * Item = new cItem(); + int BurnTime; + + const AStringVector & Sides = StringSplit(Line, "="); + if (Sides.size() != 2) { + LOGWARNING("furnace.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } - // Add to fuel list: - Fuel F; - F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); - F.BurnTime = IBurnTime; - m_pState->Fuel.push_back(F); -} - - - - + if (!ParseItem(Sides[0], *Item)) + { + LOGWARNING("furnace.txt: line %d: Cannot parse item \"%s\".", a_LineNum, Sides[0].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; + } -void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) -{ - int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; - int OItemID = 0, OItemCount = 0, OItemHealth = 0; - AString::size_type BeginPos = 0; // Begin at start of line - - if ( - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "@", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "=", a_Line, a_LineNum, IBurnTime) || // Read item burn time - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, OItemID) || // Read result ID - !ReadOptionalNumbers(BeginPos, ":", "012456789", a_Line, a_LineNum, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value - ) + if (!StringToInteger(Sides[1], BurnTime)) { + LOGWARNING("furnace.txt: line %d: Cannot parse burn time.", a_LineNum); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } - // Add to recipe list - Recipe R; - R.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); - R.Out = new cItem((ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth); - R.CookTime = IBurnTime; - m_pState->Recipes.push_back(R); + // Add to fuel list: + cFuel Fuel; + Fuel.In = Item; + Fuel.BurnTime = BurnTime; + m_pState->Fuel.push_back(Fuel); } -void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) +void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) { - LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); -} - - + AString Line(a_Line); + Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); + int CookTime = 200; + cItem * InputItem = new cItem(); + cItem * OutputItem = new cItem(); + const AStringVector & Sides = StringSplit(Line, "="); + if (Sides.size() != 2) + { + LOGWARNING("furnace.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; + } -bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue) -{ - // TODO: replace atoi with std::stoi - AString::size_type End; - if (a_IsLastValue) + const AStringVector & InputSplit = StringSplit(Sides[0], "@"); + if (!ParseItem(InputSplit[0], *InputItem)) { - End = a_Text.find_first_not_of(a_Delimiter, a_Begin); + LOGWARNING("furnace.txt: line %d: Cannot parse input item \"%s\".", a_LineNum, InputSplit[0].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } - else + + if (InputSplit.size() > 1) { - End = a_Text.find_first_of(a_Delimiter, a_Begin); - if (End == AString::npos) + if (!StringToInteger(InputSplit[1], CookTime)) { - PrintParseError(a_Line, a_Begin, a_Delimiter); - return false; + LOGWARNING("furnace.txt: line %d: Cannot parse cook time \"%s\".", a_LineNum, InputSplit[1].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } } - - // stoi won't throw an exception if the string is alphanumeric, we should check for this - if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin))) + + if (!ParseItem(Sides[1], *OutputItem)) { - PrintParseError(a_Line, a_Begin, "number"); - return false; + LOGWARNING("furnace.txt: line %d: Cannot parse output item \"%s\".", a_LineNum, Sides[1].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } - a_Value = atoi(a_Text.substr(a_Begin, End - a_Begin).c_str()); - a_Begin = End + 1; // Jump over delimiter - return true; + cRecipe Recipe; + Recipe.In = InputItem; + Recipe.Out = OutputItem; + Recipe.CookTime = CookTime; + m_pState->Recipes.push_back(Recipe); } -bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue) +bool cFurnaceRecipe::ParseItem(const AString & a_String, cItem & a_Item) { - // TODO: replace atoi with std::stoi - AString::size_type End, Begin = a_Begin; - - End = a_Text.find_first_of(a_DelimiterOne, Begin); - if (End != AString::npos) - { - if (DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) - { - a_ValueOne = std::atoi(a_Text.substr(Begin, End - Begin).c_str()); - Begin = End + 1; + AString ItemString = a_String; + + const AStringVector & SplitAmount = StringSplit(ItemString, ","); + ItemString = SplitAmount[0]; - if (a_IsLastValue) - { - End = a_Text.find_first_not_of(a_DelimiterTwo, Begin); - } - else - { - End = a_Text.find_first_of(a_DelimiterTwo, Begin); - if (End == AString::npos) - { - PrintParseError(a_Line, Begin, a_DelimiterTwo); - return false; - } - } + const AStringVector & SplitMeta = StringSplit(ItemString, ":"); + ItemString = SplitMeta[0]; - // stoi won't throw an exception if the string is alphanumeric, we should check for this - if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) - { - PrintParseError(a_Line, Begin, "number"); - return false; - } - a_ValueTwo = atoi(a_Text.substr(Begin, End - Begin).c_str()); + if (!StringToItem(ItemString, a_Item)) + { + return false; + } - a_Begin = End + 1; // Jump over delimiter - return true; - } - else + if (SplitAmount.size() > 1) + { + if (!StringToInteger(SplitAmount[1].c_str(), a_Item.m_ItemCount)) { - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); + return false; } } - - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); -} - - - - -bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String) -{ - // TODO: replace this with std::all_of(a_String.begin(), a_String.end(), isdigit) - return (a_String.find_first_not_of("0123456789") == AString::npos); + if (SplitMeta.size() > 1) + { + if (!StringToInteger(SplitMeta[1].c_str(), a_Item.m_ItemDamage)) + { + return false; + } + } + return true; } @@ -266,19 +245,19 @@ void cFurnaceRecipe::ClearRecipes(void) { for (RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr) { - Recipe R = *itr; - delete R.In; - R.In = NULL; - delete R.Out; - R.Out = NULL; + cRecipe Recipe = *itr; + delete Recipe.In; + Recipe.In = NULL; + delete Recipe.Out; + Recipe.Out = NULL; } m_pState->Recipes.clear(); for (FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr) { - Fuel F = *itr; - delete F.In; - F.In = NULL; + cFuel Fuel = *itr; + delete Fuel.In; + Fuel.In = NULL; } m_pState->Fuel.clear(); } @@ -287,21 +266,21 @@ void cFurnaceRecipe::ClearRecipes(void) -const cFurnaceRecipe::Recipe * cFurnaceRecipe::GetRecipeFrom(const cItem & a_Ingredient) const +const cFurnaceRecipe::cRecipe * cFurnaceRecipe::GetRecipeFrom(const cItem & a_Ingredient) const { - const Recipe * BestRecipe = 0; + const cRecipe * BestRecipe = 0; for (RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr) { - const Recipe & R = *itr; - if ((R.In->m_ItemType == a_Ingredient.m_ItemType) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount)) + const cRecipe & Recipe = *itr; + if ((Recipe.In->m_ItemType == a_Ingredient.m_ItemType) && (Recipe.In->m_ItemCount <= a_Ingredient.m_ItemCount)) { - if (BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount)) + if (BestRecipe && (BestRecipe->In->m_ItemCount > Recipe.In->m_ItemCount)) { continue; } else { - BestRecipe = &R; + BestRecipe = &Recipe; } } } @@ -317,16 +296,16 @@ int cFurnaceRecipe::GetBurnTime(const cItem & a_Fuel) const int BestFuel = 0; for (FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr) { - const Fuel & F = *itr; - if ((F.In->m_ItemType == a_Fuel.m_ItemType) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount)) + const cFuel & Fuel = *itr; + if ((Fuel.In->m_ItemType == a_Fuel.m_ItemType) && (Fuel.In->m_ItemCount <= a_Fuel.m_ItemCount)) { - if (BestFuel > 0 && (BestFuel > F.BurnTime)) + if (BestFuel > 0 && (BestFuel > Fuel.BurnTime)) { continue; } else { - BestFuel = F.BurnTime; + BestFuel = Fuel.BurnTime; } } } diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 77ed35a57..de3ee56a0 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -19,23 +19,23 @@ public: void ReloadRecipes(void); - struct Fuel + struct cFuel { cItem * In; int BurnTime; ///< How long this fuel burns, in ticks }; - struct Recipe + struct cRecipe { cItem * In; cItem * Out; int CookTime; ///< How long this recipe takes to smelt, in ticks }; - /// Returns a recipe for the specified input, NULL if no recipe found - const Recipe * GetRecipeFrom(const cItem & a_Ingredient) const; + /** Returns a recipe for the specified input, NULL if no recipe found */ + const cRecipe * GetRecipeFrom(const cItem & a_Ingredient) const; - /// Returns the amount of time that the specified fuel burns, in ticks + /** Returns the amount of time that the specified fuel burns, in ticks */ int GetBurnTime(const cItem & a_Fuel) const; private: @@ -49,27 +49,8 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, int a_LineNum); - /** Calls LOGWARN with the line, position, and error */ - static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing); - - /** Reads a number from a string given, starting at a given position and ending at a delimiter given - Updates beginning position to the delimiter found + 1, and updates the value to the one read - If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing - Otherwise, the function will return true - */ - static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false); - - /** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given - Updates beginning position to the second delimiter found + 1, and updates the values to the ones read - If it encounters a substring that is not fully numeric whilst reading the second value, it will call SetParseError() and return false; the caller should abort processing - If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber() - True will be returned definitively for an optional value that is valid - */ - static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false); - - /** Uses std::all_of to determine if a string contains only digits */ - static bool DoesStringContainOnlyNumbers(const AString & a_String); - + /** Parses an item string in the format "[^][,]", returns true if successful. */ + bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; sFurnaceRecipeState * m_pState; -- cgit v1.2.3 From 66417f7a48c36b63a73d8fddc147ef5b90a91e09 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 19:29:54 +0200 Subject: Fixed wrong doxy-comment. --- src/FurnaceRecipe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index de3ee56a0..e3840d0d9 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -49,7 +49,7 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, int a_LineNum); - /** Parses an item string in the format "[^][,]", returns true if successful. */ + /** Parses an item string in the format "[:][,]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; -- cgit v1.2.3 From 0d392f53ed5ef96886003afd90c6ce37c16dc7d3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 20:53:41 +0200 Subject: Fixed compile warnings. --- src/FurnaceRecipe.cpp | 6 +++--- src/FurnaceRecipe.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index eb64e0a91..eec76fa4a 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -77,7 +77,7 @@ void cFurnaceRecipe::ReloadRecipes(void) size_t FirstCommentSymbol = ParsingLine.find('#'); if ((FirstCommentSymbol != AString::npos) && (FirstCommentSymbol != 0)) { - ParsingLine.erase(ParsingLine.begin() + FirstCommentSymbol, ParsingLine.end()); + ParsingLine.erase(ParsingLine.begin() + (const long)FirstCommentSymbol, ParsingLine.end()); } switch (ParsingLine[0]) @@ -109,7 +109,7 @@ void cFurnaceRecipe::ReloadRecipes(void) -void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) +void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_LineNum) { AString Line(a_Line); Line.erase(Line.begin()); // Remove the beginning "!" @@ -151,7 +151,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) -void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) +void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum) { AString Line(a_Line); Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index e3840d0d9..207480fa9 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -43,11 +43,11 @@ private: /** Parses the fuel contained in the line, adds it to m_pState's fuels. Logs a warning to the console on input error. */ - void AddFuelFromLine(const AString & a_Line, int a_LineNum); + void AddFuelFromLine(const AString & a_Line, unsigned int a_LineNum); /** Parses the recipe contained in the line, adds it to m_pState's recipes. Logs a warning to the console on input error. */ - void AddRecipeFromLine(const AString & a_Line, int a_LineNum); + void AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum); /** Parses an item string in the format "[:][,]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); -- cgit v1.2.3 From b6d77d9679b7b26f31d6249b66b49d52eabe5bb6 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 20:26:08 +0100 Subject: Init RankMgr pointer to NULL --- src/Protocol/MojangAPI.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 4e5c41a8a..28da83c31 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -158,7 +158,8 @@ cMojangAPI::cMojangAPI(void) : m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_UUIDToProfileServer(DEFAULT_UUID_TO_PROFILE_SERVER), - m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS) + m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS), + m_RankMgr(NULL) { } -- cgit v1.2.3 From 3e7332c70ceb372afcd2abf431c6b4c222fe9359 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 20:28:41 +0100 Subject: Delete the entity before removing from the list Old code was calling dereference on invalid iterator --- src/SetChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index 97903074a..bfe59fbcb 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -134,8 +134,8 @@ void cSetChunkData::RemoveInvalidBlockEntities(void) ); cBlockEntityList::iterator itr2 = itr; itr2++; - m_BlockEntities.erase(itr); delete *itr; + m_BlockEntities.erase(itr); itr = itr2; } else -- cgit v1.2.3 From af125d2a61096c6eef97d86bc815196c8d5275de Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 22:04:52 +0200 Subject: Use std::auto_ptr --- src/FurnaceRecipe.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index eec76fa4a..d200ef3d7 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -115,7 +115,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line Line.erase(Line.begin()); // Remove the beginning "!" Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); - cItem * Item = new cItem(); + std::auto_ptr Item(new cItem); int BurnTime; const AStringVector & Sides = StringSplit(Line, "="); @@ -142,7 +142,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line // Add to fuel list: cFuel Fuel; - Fuel.In = Item; + Fuel.In = Item.release(); Fuel.BurnTime = BurnTime; m_pState->Fuel.push_back(Fuel); } @@ -157,8 +157,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); int CookTime = 200; - cItem * InputItem = new cItem(); - cItem * OutputItem = new cItem(); + std::auto_ptr InputItem(new cItem()); + std::auto_ptr OutputItem(new cItem()); const AStringVector & Sides = StringSplit(Line, "="); if (Sides.size() != 2) @@ -194,8 +194,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li } cRecipe Recipe; - Recipe.In = InputItem; - Recipe.Out = OutputItem; + Recipe.In = InputItem.release(); + Recipe.Out = OutputItem.release(); Recipe.CookTime = CookTime; m_pState->Recipes.push_back(Recipe); } -- cgit v1.2.3 From 361b7d5379faf59140befa9d3a6c88fcad75535b Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 21:14:42 +0100 Subject: Changed null check to assert Changed the null check to clarify that the function should not be called before the entity has been attached to a world. --- src/BlockEntities/CommandBlockEntity.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index dd0858378..43cdb92fb 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -188,12 +188,10 @@ void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) void cCommandBlockEntity::Execute() { - if (m_World != NULL) + ASSERT(m_World != NULL); //Execute should not be called before the command block is attached to a world + if (!m_World->AreCommandBlocksEnabled()) { - if (!m_World->AreCommandBlocksEnabled()) - { - return; - } + return; } class CommandBlockOutCb : -- cgit v1.2.3 From 468c2558d632bb5702c12577c74967c50327accf Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 21:26:02 +0100 Subject: Removed isDone check The same data is returned by executeStep so why execute a call when you have the data. --- src/RankManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index dc6eec9e4..e5896f8f3 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -477,8 +477,8 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); stmt.bind(1, a_PlayerUUID); - stmt.executeStep(); - if (stmt.isDone()) + // executeStep returns false on no data + if (!stmt.executeStep()) { // No data returned from the DB return AString(); -- cgit v1.2.3 From 1e60265a909884df3c440e298d1400889c07b5fb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 13:33:17 +0200 Subject: Fixed style. --- src/BlockEntities/CommandBlockEntity.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 43cdb92fb..20702a9ac 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -188,7 +188,8 @@ void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) void cCommandBlockEntity::Execute() { - ASSERT(m_World != NULL); //Execute should not be called before the command block is attached to a world + ASSERT(m_World != NULL); // Execute should not be called before the command block is attached to a world + if (!m_World->AreCommandBlocksEnabled()) { return; -- cgit v1.2.3 From ea39c1d21cab2533504172f735e46b28664c8327 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 13:43:10 +0200 Subject: Avoid false positive in style check. --- src/FurnaceRecipe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 207480fa9..6a1650695 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -49,7 +49,7 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum); - /** Parses an item string in the format "[:][,]", returns true if successful. */ + /** Parses an item string in the format "[: ][, ]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; -- cgit v1.2.3 From f22f67a63ced1e99abafd09026b1b4955fb3664e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:29:13 +0200 Subject: Fixed MSVC warning. --- src/Entities/ArrowEntity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index c3e7c5d79..954e0a267 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -114,8 +114,8 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { - int ExtraDamage = 0.25 * (PowerLevel + 1); - Damage += ceil(ExtraDamage); + int ExtraDamage = (int)ceil(0.25 * (PowerLevel + 1)); + Damage += ExtraDamage; } int KnockbackAmount = 1; -- cgit v1.2.3 From 7d8a474f13c97186eb6d17b3dcf36dd225436fae Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:31:05 +0200 Subject: Fixed MSVC compilation, improved performance. We're not creating copies of the equipped items anymore, rather, we're using pointers to them. Also pow() is needlessly slow for a simple second power, and MSVC2008 was confused about the pow() overloads. --- src/Entities/Entity.cpp | 89 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index e36ed6c37..dde45c360 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -317,7 +317,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; + const cEnchantments & Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); int SmiteLevel = Enchantments.GetLevel(cEnchantments::enchSmite); @@ -325,7 +325,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (SharpnessLevel > 0) { - a_TDI.FinalDamage += 1.25 * SharpnessLevel; + a_TDI.FinalDamage += (int)ceil(1.25 * SharpnessLevel); } else if (SmiteLevel > 0) { @@ -339,7 +339,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtWither: case cMonster::mtZombiePigman: { - a_TDI.FinalDamage += 2.5 * SmiteLevel; + a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel); break; } } @@ -356,7 +356,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtCaveSpider: case cMonster::mtSilverfish: { - a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + a_TDI.RawDamage += (int)ceil(2.5 * BaneOfArthropodsLevel); // TODO: Add slowness effect break; @@ -396,11 +396,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - cItem Item = ArmorItems[i]; - ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); + const cItem * Item = ArmorItems[i]; + ThornsLevel = std::max(ThornsLevel, Item->m_Enchantments.GetLevel(cEnchantments::enchThorns)); } if (ThornsLevel > 0) @@ -437,33 +437,38 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - cItem Item = ArmorItems[i]; - if (Item.m_Enchantments.GetLevel(cEnchantments::enchProtection) > 0) + const cItem * Item = ArmorItems[i]; + int Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProtection); + if (Level > 0) { - EPFProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + Level * Level) * 0.75 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFireProtection); + if (Level > 0) { - EPFFireProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + Level * Level) * 1.25 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); + if (Level > 0) { - EPFFeatherFalling += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + Level * Level) * 2.5 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); + if (Level > 0) { - EPFBlastProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + Level * Level) * 1.5 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); + if (Level > 0) { - EPFProjectileProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + Level * Level) * 1.5 / 3; } } @@ -476,14 +481,20 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) EPFBlastProtection = EPFBlastProtection / TotalEPF; EPFProjectileProtection = EPFProjectileProtection / TotalEPF; - if (TotalEPF > 25) TotalEPF = 25; + if (TotalEPF > 25) + { + TotalEPF = 25; + } cFastRandom Random; - float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01; + float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01f; TotalEPF = ceil(TotalEPF * RandomValue); - if (TotalEPF > 20) TotalEPF = 20; + if (TotalEPF > 20) + { + TotalEPF = 20; + } EPFProtection = TotalEPF * EPFProtection; EPFFireProtection = TotalEPF * EPFFireProtection; @@ -493,21 +504,38 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) int RemovedDamage = 0; - if (a_TDI.DamageType != dtInVoid) RemovedDamage += ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtAdmin)) + { + RemovedDamage += (int)ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + } - if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) RemovedDamage += ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) + { + RemovedDamage += (int)ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtBurning) RemovedDamage += ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtBurning) + { + RemovedDamage += (int)ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtExplosion) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtExplosion) + { + RemovedDamage += (int)ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtProjectile) + { + RemovedDamage += (int)ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.FinalDamage < RemovedDamage) RemovedDamage = 0; + if (a_TDI.FinalDamage < RemovedDamage) + { + RemovedDamage = 0; + } a_TDI.FinalDamage -= RemovedDamage; } - m_Health -= (short)a_TDI.FinalDamage; @@ -515,7 +543,8 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); - if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs + // Add knockback: + if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment if (KnockbackLevel < 1) -- cgit v1.2.3 From 8821c476bb57a7fe4f45b0ff755394faa378fbef Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:35:52 +0200 Subject: Fixed previous commit's wrong assumptions. The equipment-getting functions return a copy already, so we can't take a pointer, really. --- src/Entities/Entity.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index dde45c360..89d1cffa1 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -396,11 +396,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - const cItem * Item = ArmorItems[i]; - ThornsLevel = std::max(ThornsLevel, Item->m_Enchantments.GetLevel(cEnchantments::enchThorns)); + const cItem & Item = ArmorItems[i]; + ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); } if (ThornsLevel > 0) @@ -437,35 +437,35 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - const cItem * Item = ArmorItems[i]; - int Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProtection); + const cItem & Item = ArmorItems[i]; + int Level = Item.m_Enchantments.GetLevel(cEnchantments::enchProtection); if (Level > 0) { EPFProtection += (6 + Level * Level) * 0.75 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFireProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection); if (Level > 0) { EPFFireProtection += (6 + Level * Level) * 1.25 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); if (Level > 0) { EPFFeatherFalling += (6 + Level * Level) * 2.5 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); if (Level > 0) { EPFBlastProtection += (6 + Level * Level) * 1.5 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); if (Level > 0) { EPFProjectileProtection += (6 + Level * Level) * 1.5 / 3; -- cgit v1.2.3 From 4c9abab2d12fa3900a8339ef125fe0808e182eaf Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Mon, 1 Sep 2014 15:01:56 +0200 Subject: fix possibility of a twice generated chunk --- src/Generating/ChunkGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index a1c3d50cc..845202358 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -230,7 +230,6 @@ void cChunkGenerator::Execute(void) } cChunkCoords coords = m_Queue.front(); // Get next coord from queue - m_Queue.erase( m_Queue.begin()); // Remove coordinate from queue bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT); Lock.Unlock(); // Unlock ASAP m_evtRemoved.Set(); @@ -254,6 +253,8 @@ void cChunkGenerator::Execute(void) LOGD("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ); DoGenerate(coords.m_ChunkX, coords.m_ChunkZ); + m_Queue.erase(m_Queue.begin()); // Remove coordinate from queue + NumChunksGenerated++; } // while (!bStop) } -- cgit v1.2.3 From 022f5f141dae1c97cb17a046404755a0be36c26d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 16:10:40 +0200 Subject: Fixed Bindings regeneration under MSVC. --- src/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37657ba91..2d96662a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -256,6 +256,11 @@ set(EXECUTABLE MCServer) if (MSVC) get_directory_property(BINDING_OUTPUTS DIRECTORY "Bindings" DEFINITION BINDING_OUTPUTS) get_directory_property(BINDING_DEPENDENCIES DIRECTORY "Bindings" DEFINITION BINDING_DEPENDENCIES) + + # The paths in BINDING_DEPENDENCIES are relative to the Bindings folder, convert them relative to this folder: + foreach (dep ${BINDING_DEPENDENCIES}) + list (APPEND BINDINGS_DEPENDENCIES "Bindings/${dep}") + endforeach(dep) ADD_CUSTOM_COMMAND( OUTPUT ${BINDING_OUTPUTS} @@ -268,7 +273,7 @@ if (MSVC) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/ # add any new generation dependencies here - DEPENDS ${BINDING_DEPENDENCIES} + DEPENDS ${BINDINGS_DEPENDENCIES} ) endif() -- cgit v1.2.3 From de30a8c8c6fac58a137a9d1faf80acc64c04050c Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 1 Sep 2014 18:18:07 +0100 Subject: Make sure packets are valid Fixes CID 66408, 66409 and 72045 --- src/Protocol/ProtocolRecognizer.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c831da251..8b395230a 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -979,9 +979,18 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema AString ServerAddress; short ServerPort; UInt32 NextState; - m_Buffer.ReadVarUTF8String(ServerAddress); - m_Buffer.ReadBEShort(ServerPort); - m_Buffer.ReadVarInt(NextState); + if (!m_Buffer.ReadVarUTF8String(ServerAddress)) + { + break; + } + if (!m_Buffer.ReadBEShort(ServerPort)) + { + break; + } + if (!m_Buffer.ReadVarInt(NextState)) + { + break; + } m_Buffer.CommitRead(); m_Protocol = new cProtocol172(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; @@ -991,9 +1000,18 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema AString ServerAddress; short ServerPort; UInt32 NextState; - m_Buffer.ReadVarUTF8String(ServerAddress); - m_Buffer.ReadBEShort(ServerPort); - m_Buffer.ReadVarInt(NextState); + if (!m_Buffer.ReadVarUTF8String(ServerAddress)) + { + break; + } + if (!m_Buffer.ReadBEShort(ServerPort)) + { + break; + } + if (!m_Buffer.ReadVarInt(NextState)) + { + break; + } m_Buffer.CommitRead(); m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; -- cgit v1.2.3 From 7c4cb9a3852e33d8bcc5f8283485e833c6eab93e Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 1 Sep 2014 20:12:56 +0200 Subject: Added CustomName to cMonster. --- src/Entities/Pawn.cpp | 9 ++++++--- src/Mobs/Monster.cpp | 29 +++++++++++++++++++++++++++++ src/Mobs/Monster.h | 20 +++++++++++++++++++- src/Protocol/Protocol17x.cpp | 10 ++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index fe6c24a7a..fc8ca3d47 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -9,9 +9,9 @@ -cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height): - super(a_EntityType, 0, 0, 0, a_Width, a_Height), - m_EntityEffects(tEffectMap()) +cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) : + super(a_EntityType, 0, 0, 0, a_Width, a_Height) + , m_EntityEffects(tEffectMap()) { } @@ -111,3 +111,6 @@ void cPawn::ClearEntityEffects() RemoveEntityEffect(EffectType); } } + + + diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index f7ee0b0c0..6a477ca1c 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -75,6 +75,8 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_IdleInterval(0) , m_DestroyTimer(0) , m_MobType(a_MobType) + , m_CustomName("") + , m_CustomNameAlwaysVisible(false) , m_SoundHurt(a_SoundHurt) , m_SoundDeath(a_SoundDeath) , m_AttackRate(3) @@ -679,6 +681,33 @@ void cMonster::InStateEscaping(float a_Dt) +void cMonster::SetCustomName(const AString & a_CustomName) +{ + m_CustomName = a_CustomName; + + // The maximal length is 64 + if (a_CustomName.length() > 64) + { + m_CustomName = a_CustomName.substr(0, 64); + } + + m_World->BroadcastEntityMetadata(*this); +} + + + + + +void cMonster::SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible) +{ + m_CustomNameAlwaysVisible = a_CustomNameAlwaysVisible; + m_World->BroadcastEntityMetadata(*this); +} + + + + + void cMonster::GetMonsterConfig(const AString & a_Name) { cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, a_Name); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index cdbd26c09..ce4e36a46 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -144,7 +144,23 @@ public: virtual bool IsSitting (void) const { return false; } // tolua_begin - + + /** Returns true if the monster has a custom name. */ + bool HasCustomName(void) const { return !m_CustomName.empty(); } + + /** Gets the custom name of the monster. If no custom name is set, the function returns a empty string. */ + const AString & GetCustomName(void) const { return m_CustomName; } + + /** Sets the custom name of the monster. You see the name over the monster. */ + void SetCustomName(const AString & a_CustomName); + + /** Is the custom name of this monster always visible? If not, you only see the name when you sight the mob. */ + bool IsCustomNameAlwaysVisible(void) const { return m_CustomNameAlwaysVisible; } + + /** Sets the custom name visiblity of this monster. + If false, you only see the name when you sight the mob. If true, you always see the custom name. */ + void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible); + /// Translates MobType enum to a string, empty string if unknown static AString MobTypeToString(eType a_MobType); @@ -228,6 +244,8 @@ protected: float m_DestroyTimer; eType m_MobType; + AString m_CustomName; + bool m_CustomNameAlwaysVisible; AString m_SoundHurt; AString m_SoundDeath; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 1091b877f..ed9812377 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1,3 +1,4 @@ + // Protocol17x.cpp /* @@ -3021,6 +3022,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } } // switch (a_Mob.GetType()) + + // Custom name: + if (a_Mob.HasCustomName()) + { + WriteByte(0x8a); + WriteString(a_Mob.GetCustomName()); + WriteByte(0x0b); + WriteByte(a_Mob.IsCustomNameAlwaysVisible() ? 1 : 0); + } } -- cgit v1.2.3 From dfed6f94ca78f2e104ed316d83400b0ca74cb79a Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 1 Sep 2014 21:05:45 +0200 Subject: Added name tag --- src/Entities/Boat.cpp | 2 ++ src/Entities/Entity.h | 2 +- src/Entities/ItemFrame.cpp | 2 ++ src/Entities/Minecart.cpp | 5 +++-- src/Mobs/Monster.cpp | 19 +++++++++++++++++++ src/Mobs/Monster.h | 2 ++ src/Mobs/Sheep.cpp | 2 ++ 7 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 8ff8866a1..328a70846 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -62,6 +62,8 @@ bool cBoat::DoTakeDamage(TakeDamageInfo & TDI) void cBoat::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (m_Attachee != NULL) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b9c280b6b..774cdb062 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -447,7 +447,7 @@ public: // tolua_end /// Called when the specified player right-clicks this entity - virtual void OnRightClicked(cPlayer &) {} + virtual void OnRightClicked(cPlayer & a_Player) {} /// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy(). virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index 0bc10ec60..3ccb95998 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -22,6 +22,8 @@ cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_ void cItemFrame::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (!m_Item.IsEmpty()) { // Item not empty, rotate, clipping values to zero to three inclusive diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 1501eea84..5fabbb542 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1072,6 +1072,8 @@ cRideableMinecart::cRideableMinecart(double a_X, double a_Y, double a_Z, const c void cRideableMinecart::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (m_Attachee != NULL) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) @@ -1124,8 +1126,7 @@ void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item) void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) { - // Show the chest UI window to the player - // TODO + // TODO: Show the chest UI window to the player } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 6a477ca1c..a89fa32a3 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -553,6 +553,25 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI) +void cMonster::OnRightClicked(cPlayer & a_Player) +{ + super::OnRightClicked(a_Player); + + const cItem & EquippedItem = a_Player.GetEquippedItem(); + if ((EquippedItem.m_ItemType == E_ITEM_NAME_TAG) && !EquippedItem.m_CustomName.empty()) + { + SetCustomName(EquippedItem.m_CustomName); + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + } +} + + + + + // Checks to see if EventSeePlayer should be fired // monster sez: Do I see the player void cMonster::CheckEventSeePlayer(void) diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index ce4e36a46..f14a4f100 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -92,6 +92,8 @@ public: virtual void KilledBy(TakeDamageInfo & a_TDI) override; + virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void MoveToPosition(const Vector3d & a_Position); // tolua_export virtual bool ReachedDestination(void); diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 9fb47201d..ee3236bba 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -47,6 +47,8 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSheep::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + const cItem & EquippedItem = a_Player.GetEquippedItem(); if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) { -- cgit v1.2.3 From 6f18d01b5148e68f640c28dc303efe3cef328a1d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 21:17:22 +0200 Subject: Fixed off-by-one errors in cChunkDef asserts. --- src/ChunkDef.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 51075ab4a..b8b4291c7 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -197,32 +197,32 @@ public: inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); return a_HeightMap[a_X + Width * a_Z]; } inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); a_HeightMap[a_X + Width * a_Z] = a_Height; } inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); return a_BiomeMap[a_X + Width * a_Z]; } inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); a_BiomeMap[a_X + Width * a_Z] = a_Biome; } -- cgit v1.2.3 From 7695471ff9423c14d9e7188a85a270b368760402 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Mon, 1 Sep 2014 21:37:36 +0200 Subject: added multicache class definition --- src/Generating/BioGen.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src') diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index 227ec97d7..a53d8bca2 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -77,7 +77,42 @@ protected: } ; +class cBioGenMulticache : + public cBiomeGen +{ + + typedef cBiomeGen super; + +public: + cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CacheLength); // Doesn't take ownership of a_BioGenToCache + ~cBioGenMulticache(); + +protected: + + cBiomeGen * m_BioGenToCache; + struct sCacheData + { + int m_ChunkX; + int m_ChunkZ; + cChunkDef::BiomeMap m_BiomeMap; + }; + + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data + int m_CacheSize; + int m_CacheLength; + + int **m_CachesOrder; // MRU-ized order, indices into the multiple m_CachesData array + sCacheData ** m_CachesData; + + // Cache statistics + int m_NumHits; + int m_NumMisses; + int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; + virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; +}; /// Base class for generators that use a list of available biomes. This class takes care of the list. -- cgit v1.2.3 From b1da567f3db56f7e8ba735817eeb63dbd8d69d9e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 21:43:03 +0200 Subject: Pickups combine only within one chunk. This greatly improves performance of the tick thread. --- src/Entities/Pickup.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index aab534f41..87b5bed07 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -150,10 +150,14 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) } } - if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup + // Try to combine the pickup with adjacent same-item pickups: + if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine if already full { + // By using a_Chunk's ForEachEntity() instead of cWorld's, pickups don't combine across chunk boundaries. + // That is a small price to pay for not having to traverse the entire world for each entity. + // The speedup in the tick thread is quite considerable. cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this); - m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries + a_Chunk.ForEachEntity(PickupCombiningCallback); if (PickupCombiningCallback.FoundMatchingPickup()) { m_World->BroadcastEntityMetadata(*this); -- cgit v1.2.3 From 77409d47eb98eb691f852728cd8e013d0fc14185 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Mon, 1 Sep 2014 22:33:58 +0200 Subject: adding the multicache behavior --- src/Generating/BioGen.cpp | 115 +++++++++++++++++++++++++++++++++ src/Generating/BioGen.h | 6 +- src/Generating/ComposableGenerator.cpp | 2 +- 3 files changed, 119 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 8fad9f5c9..c9aeffa54 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -208,6 +208,121 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) +//////////////////////////////////////////////////////////////////////////////// +// cBioGenMulticache: + +cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CachesLength) : +m_BioGenToCache(a_BioGenToCache), +m_CacheSize(a_CacheSize), +m_CachesLength(a_CachesLength), +m_CachesOrder(new int*[a_CachesLength * a_CachesLength]), +m_CachesData(new sCacheData*[a_CachesLength * a_CachesLength]), +m_NumHits(0), +m_NumMisses(0), +m_TotalChain(0) +{ + for (int i = 0; i < m_CachesLength * m_CachesLength; i++) { + sCacheData * cacheData = m_CachesData[i] = new sCacheData[m_CacheSize]; + int * cacheOrder = m_CachesOrder[i] = new int[m_CacheSize]; + + for (int j = 0; j < m_CacheSize; j++) + { + cacheOrder[j] = j; + cacheData[j].m_ChunkX = 0x7fffffff; + cacheData[j].m_ChunkZ = 0x7fffffff; + } + } + +} + + + + + +cBioGenMulticache::~cBioGenMulticache() +{ + for (int i = 0; i < m_CachesLength * m_CachesLength; i++) { + delete[] m_CachesData[i]; + delete[] m_CachesOrder[i]; + } + delete[] m_CachesData; + m_CachesData = NULL; + delete[] m_CachesOrder; + m_CachesOrder = NULL; +} + + + + + +void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) +{ + if (((m_NumHits + m_NumMisses) % 1024) == 10) + { + LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); + LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); + } + + int cacheIdx = ((unsigned int)a_ChunkX % m_CachesLength) * m_CachesLength + ((unsigned int)a_ChunkZ % m_CachesLength); + sCacheData * cacheData = m_CachesData[cacheIdx]; + int * cacheOrder = m_CachesOrder[cacheIdx]; + + for (int i = 0; i < m_CacheSize; i++) + { + if ( + (cacheData[cacheOrder[i]].m_ChunkX != a_ChunkX) || + (cacheData[cacheOrder[i]].m_ChunkZ != a_ChunkZ) + ) + { + continue; + } + // Found it in the cache + int Idx = cacheOrder[i]; + + // Move to front: + for (int j = i; j > 0; j--) + { + cacheOrder[j] = cacheOrder[j - 1]; + } + cacheOrder[0] = Idx; + + // Use the cached data: + memcpy(a_BiomeMap, cacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); + + m_NumHits++; + m_TotalChain += i; + return; + } // for i - cache + + // Not in the cache: + m_NumMisses++; + m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); + + // Insert it as the first item in the MRU order: + int Idx = cacheOrder[m_CacheSize - 1]; + for (int i = m_CacheSize - 1; i > 0; i--) + { + cacheOrder[i] = cacheOrder[i - 1]; + } // for i - m_CacheOrder[] + cacheOrder[0] = Idx; + memcpy(cacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap)); + cacheData[Idx].m_ChunkX = a_ChunkX; + cacheData[Idx].m_ChunkZ = a_ChunkZ; +} + + + + + +void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) +{ + super::InitializeBiomeGen(a_IniFile); + m_BioGenToCache->InitializeBiomeGen(a_IniFile); +} + + + + //////////////////////////////////////////////////////////////////////////////// // cBiomeGenList: diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index a53d8bca2..f9564ed24 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -84,7 +84,7 @@ class cBioGenMulticache : typedef cBiomeGen super; public: - cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CacheLength); // Doesn't take ownership of a_BioGenToCache + cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CachesLength); // Doesn't take ownership of a_BioGenToCache ~cBioGenMulticache(); protected: @@ -100,9 +100,9 @@ protected: // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data int m_CacheSize; - int m_CacheLength; + int m_CachesLength; - int **m_CachesOrder; // MRU-ized order, indices into the multiple m_CachesData array + int ** m_CachesOrder; // MRU-ized order, indices into the multiple m_CachesData array sCacheData ** m_CachesData; // Cache statistics diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 6f4007d24..057d7accf 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -241,7 +241,7 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) } LOGD("Using a cache for biomegen of size %d.", CacheSize); m_UnderlyingBiomeGen = m_BiomeGen; - m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); + m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, 4); } } -- cgit v1.2.3 From d9afe6dd657363f4a6e42790ba4705a9b9b89e60 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Tue, 2 Sep 2014 01:13:54 +0200 Subject: adding config file entry #381 --- src/Generating/ComposableGenerator.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 057d7accf..0535e89f3 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -230,6 +230,8 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) // Add a cache, if requested: int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); + int MultiCacheLength = a_IniFile.GetValueSetI("Generator", "BiomeGenMultiCacheLength", 4); + if (CacheSize > 0) { if (CacheSize < 4) @@ -241,7 +243,14 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) } LOGD("Using a cache for biomegen of size %d.", CacheSize); m_UnderlyingBiomeGen = m_BiomeGen; - m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, 4); + if (MultiCacheLength > 0) { + LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); + m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); + } + else { + m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); + } + } } -- cgit v1.2.3 From ac4ec5117dbe0ae12e73968b6a6d6cbc1640933a Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Tue, 2 Sep 2014 10:49:46 +0200 Subject: changing implem, using vectors --- src/Generating/BioGen.cpp | 93 ++++++++--------------------------------------- src/Generating/BioGen.h | 28 ++++---------- 2 files changed, 23 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index c9aeffa54..4936fc251 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -212,27 +212,14 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) // cBioGenMulticache: cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CachesLength) : -m_BioGenToCache(a_BioGenToCache), -m_CacheSize(a_CacheSize), m_CachesLength(a_CachesLength), -m_CachesOrder(new int*[a_CachesLength * a_CachesLength]), -m_CachesData(new sCacheData*[a_CachesLength * a_CachesLength]), -m_NumHits(0), -m_NumMisses(0), -m_TotalChain(0) +m_InternalCacheLength(a_CachesLength * a_CacheSize) { - for (int i = 0; i < m_CachesLength * m_CachesLength; i++) { - sCacheData * cacheData = m_CachesData[i] = new sCacheData[m_CacheSize]; - int * cacheOrder = m_CachesOrder[i] = new int[m_CacheSize]; - - for (int j = 0; j < m_CacheSize; j++) - { - cacheOrder[j] = j; - cacheData[j].m_ChunkX = 0x7fffffff; - cacheData[j].m_ChunkZ = 0x7fffffff; - } + //m_Caches = new std::vector; + m_Caches.reserve(m_InternalCacheLength); + for (int i = 0; i < m_InternalCacheLength; i++) { + m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); } - } @@ -241,14 +228,7 @@ m_TotalChain(0) cBioGenMulticache::~cBioGenMulticache() { - for (int i = 0; i < m_CachesLength * m_CachesLength; i++) { - delete[] m_CachesData[i]; - delete[] m_CachesOrder[i]; - } - delete[] m_CachesData; - m_CachesData = NULL; - delete[] m_CachesOrder; - m_CachesOrder = NULL; + m_Caches.erase(m_Caches.cbegin(), m_Caches.cend()); } @@ -257,57 +237,10 @@ cBioGenMulticache::~cBioGenMulticache() void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - if (((m_NumHits + m_NumMisses) % 1024) == 10) - { - LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); - LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); - } - - int cacheIdx = ((unsigned int)a_ChunkX % m_CachesLength) * m_CachesLength + ((unsigned int)a_ChunkZ % m_CachesLength); - sCacheData * cacheData = m_CachesData[cacheIdx]; - int * cacheOrder = m_CachesOrder[cacheIdx]; + int cacheIdx = ((unsigned int)a_ChunkX % m_CachesLength) * m_CachesLength + + ((unsigned int)a_ChunkZ % m_CachesLength); - for (int i = 0; i < m_CacheSize; i++) - { - if ( - (cacheData[cacheOrder[i]].m_ChunkX != a_ChunkX) || - (cacheData[cacheOrder[i]].m_ChunkZ != a_ChunkZ) - ) - { - continue; - } - // Found it in the cache - int Idx = cacheOrder[i]; - - // Move to front: - for (int j = i; j > 0; j--) - { - cacheOrder[j] = cacheOrder[j - 1]; - } - cacheOrder[0] = Idx; - - // Use the cached data: - memcpy(a_BiomeMap, cacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); - - m_NumHits++; - m_TotalChain += i; - return; - } // for i - cache - - // Not in the cache: - m_NumMisses++; - m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); - - // Insert it as the first item in the MRU order: - int Idx = cacheOrder[m_CacheSize - 1]; - for (int i = m_CacheSize - 1; i > 0; i--) - { - cacheOrder[i] = cacheOrder[i - 1]; - } // for i - m_CacheOrder[] - cacheOrder[0] = Idx; - memcpy(cacheData[Idx].m_BiomeMap, a_BiomeMap, sizeof(a_BiomeMap)); - cacheData[Idx].m_ChunkX = a_ChunkX; - cacheData[Idx].m_ChunkZ = a_ChunkZ; + m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } @@ -316,8 +249,12 @@ void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMa void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) { - super::InitializeBiomeGen(a_IniFile); - m_BioGenToCache->InitializeBiomeGen(a_IniFile); + //super::InitializeBiomeGen(a_IniFile); + for (auto it = m_Caches.begin(); it != m_Caches.end(); it++) + { + cBiomeGen * tmp = *it; + tmp->InitializeBiomeGen(a_IniFile); + } } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index f9564ed24..feb449c06 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -77,6 +77,9 @@ protected: } ; + + + class cBioGenMulticache : public cBiomeGen { @@ -88,33 +91,18 @@ public: ~cBioGenMulticache(); protected: - - cBiomeGen * m_BioGenToCache; - - struct sCacheData - { - int m_ChunkX; - int m_ChunkZ; - cChunkDef::BiomeMap m_BiomeMap; - }; - - // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data - int m_CacheSize; int m_CachesLength; - - int ** m_CachesOrder; // MRU-ized order, indices into the multiple m_CachesData array - sCacheData ** m_CachesData; - - // Cache statistics - int m_NumHits; - int m_NumMisses; - int m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) + int m_InternalCacheLength; + std::vector m_Caches; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; }; + + + /// Base class for generators that use a list of available biomes. This class takes care of the list. class cBiomeGenList : public cBiomeGen -- cgit v1.2.3 From 29811c4f2155bb3dd03b81803b58df45e15b84f4 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Tue, 2 Sep 2014 18:05:53 +0200 Subject: fixing memory leak --- src/Generating/BioGen.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 4936fc251..698b9463b 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -215,7 +215,6 @@ cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSiz m_CachesLength(a_CachesLength), m_InternalCacheLength(a_CachesLength * a_CacheSize) { - //m_Caches = new std::vector; m_Caches.reserve(m_InternalCacheLength); for (int i = 0; i < m_InternalCacheLength; i++) { m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); @@ -228,7 +227,10 @@ m_InternalCacheLength(a_CachesLength * a_CacheSize) cBioGenMulticache::~cBioGenMulticache() { - m_Caches.erase(m_Caches.cbegin(), m_Caches.cend()); + for (std::vector::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) + { + delete *it; + } } @@ -249,8 +251,7 @@ void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMa void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) { - //super::InitializeBiomeGen(a_IniFile); - for (auto it = m_Caches.begin(); it != m_Caches.end(); it++) + for (std::vector::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) { cBiomeGen * tmp = *it; tmp->InitializeBiomeGen(a_IniFile); -- cgit v1.2.3 From 82911f36629e77f3ec5a7a318de7151b4341ded2 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Tue, 2 Sep 2014 18:13:24 +0200 Subject: opting for size_t --- src/Generating/BioGen.cpp | 6 +++--- src/Generating/BioGen.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 698b9463b..de6869e12 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -216,7 +216,7 @@ m_CachesLength(a_CachesLength), m_InternalCacheLength(a_CachesLength * a_CacheSize) { m_Caches.reserve(m_InternalCacheLength); - for (int i = 0; i < m_InternalCacheLength; i++) { + for (size_t i = 0; i < m_InternalCacheLength; i++) { m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); } } @@ -239,8 +239,8 @@ cBioGenMulticache::~cBioGenMulticache() void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - int cacheIdx = ((unsigned int)a_ChunkX % m_CachesLength) * m_CachesLength - + ((unsigned int)a_ChunkZ % m_CachesLength); + size_t cacheIdx = ((size_t)a_ChunkX % m_CachesLength) * m_CachesLength + + ((size_t)a_ChunkZ % m_CachesLength); m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index feb449c06..bf79d242d 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -91,8 +91,8 @@ public: ~cBioGenMulticache(); protected: - int m_CachesLength; - int m_InternalCacheLength; + size_t m_CachesLength; + size_t m_InternalCacheLength; std::vector m_Caches; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -- cgit v1.2.3 From b8636ee53abf8f497aae5c8765618fad63d0552a Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Tue, 2 Sep 2014 18:18:43 +0200 Subject: forgot this one --- src/Generating/BioGen.cpp | 2 +- src/Generating/BioGen.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index de6869e12..69af5c79a 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -211,7 +211,7 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) //////////////////////////////////////////////////////////////////////////////// // cBioGenMulticache: -cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CachesLength) : +cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) : m_CachesLength(a_CachesLength), m_InternalCacheLength(a_CachesLength * a_CacheSize) { diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index bf79d242d..cfa748ec7 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -87,7 +87,7 @@ class cBioGenMulticache : typedef cBiomeGen super; public: - cBioGenMulticache(cBiomeGen * a_BioGenToCache, int a_CacheSize, int a_CachesLength); // Doesn't take ownership of a_BioGenToCache + cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache ~cBioGenMulticache(); protected: -- cgit v1.2.3 From 1bb4d7941267ee55cdf7f35fa6a0055521115960 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 19:12:35 +0200 Subject: Added SetCustomName() to players. --- src/ClientHandle.cpp | 12 ++++------ src/ClientHandle.h | 2 +- src/Entities/Player.cpp | 47 ++++++++++++++++++++++++++++++++++++- src/Entities/Player.h | 15 ++++++++++++ src/Mobs/Monster.h | 3 ++- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 23 +++++++++--------- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol132.cpp | 9 ++++++- src/Protocol/Protocol17x.cpp | 26 +++++++++++++++----- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 14 +++++++---- src/World.h | 2 +- 15 files changed, 124 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f9c6a664c..e97c126a1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -124,13 +124,11 @@ cClientHandle::~cClientHandle() if (m_Player != NULL) { cWorld * World = m_Player->GetWorld(); - if (!m_Username.empty() && (World != NULL)) - { - // Send the Offline PlayerList packet: - World->BroadcastPlayerListItem(*m_Player, false, this); - } if (World != NULL) { + // Send the Offline PlayerList packet: + World->BroadcastPlayerListItem(m_Player->GetTabListName(), false, 0, this); + World->RemovePlayer(m_Player, true); // Must be called before cPlayer::Destroy() as otherwise cChunk tries to delete the player, and then we do it again m_Player->Destroy(); } @@ -2371,9 +2369,9 @@ void cClientHandle::SendPlayerAbilities() -void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cClientHandle::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7ae70a07f..529ee4555 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -156,7 +156,7 @@ public: void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount); void SendPlayerAbilities (void); - void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline); + void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 756410989..a2934d036 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -81,7 +81,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_Team(NULL), m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL), m_bIsTeleporting(false), - m_UUID((a_Client != NULL) ? a_Client->GetUUID() : "") + m_UUID((a_Client != NULL) ? a_Client->GetUUID() : ""), + m_CustomName("") { m_InventoryWindow = new cInventoryWindow(*this); m_CurrentWindow = m_InventoryWindow; @@ -813,6 +814,28 @@ void cPlayer::SetCanFly(bool a_CanFly) +void cPlayer::SetCustomName(const AString & a_CustomName) +{ + if (m_CustomName == a_CustomName) + { + return; + } + m_World->BroadcastPlayerListItem(GetTabListName(), false, 0); // Remove old tab-list entry + + m_CustomName = a_CustomName; + if (m_CustomName.length() > 16) + { + m_CustomName = m_CustomName.substr(0, 16); + } + + m_World->BroadcastSpawnEntity(*this, m_ClientHandle); + m_World->BroadcastPlayerListItem(GetTabListName(), true, GetClientHandle()->GetPing()); +} + + + + + void cPlayer::SetFlying(bool a_IsFlying) { if (a_IsFlying == m_IsFlying) @@ -1443,6 +1466,28 @@ AString cPlayer::GetColor(void) const +AString cPlayer::GetTabListName(void) const +{ + const AString & Color = GetColor(); + + if (HasCustomName()) + { + return m_CustomName; + } + else if ((GetName().length() <= 14) && !Color.empty()) + { + return Printf("%s%s", Color.c_str(), GetName().c_str()); + } + else + { + return GetName(); + } +} + + + + + void cPlayer::TossEquippedItem(char a_Amount) { cItems Drops; diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 9821cc6d9..da64bd64f 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -251,6 +251,9 @@ public: The returned value either is empty, or includes the cChatColor::Delimiter. */ AString GetColor(void) const; + /** Returns the name that is used in the tablist. */ + AString GetTabListName(void) const; + /** tosses the item in the selected hotbar slot */ void TossEquippedItem(char a_Amount = 1); @@ -398,6 +401,16 @@ public: /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); + /** Is a custom name for this player set? */ + bool HasCustomName(void) const { return !m_CustomName.empty(); } + + /** Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string. */ + const AString & GetCustomName(void) const { return m_CustomName; } + + /** Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. + The custom name will be used in the tab-list, in the player nametag and in the tab-completion. */ + void SetCustomName(const AString & a_CustomName); + /** Gets the last position that the player slept in This is initialised to the world spawn point if the player has not slept in a bed as of yet */ @@ -562,6 +575,8 @@ protected: If no ClientHandle is given, the UUID is initialized to empty. */ AString m_UUID; + AString m_CustomName; + /** Sets the speed and sends it to the client, so that they are forced to move so. */ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index f14a4f100..a777978f6 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -153,7 +153,8 @@ public: /** Gets the custom name of the monster. If no custom name is set, the function returns a empty string. */ const AString & GetCustomName(void) const { return m_CustomName; } - /** Sets the custom name of the monster. You see the name over the monster. */ + /** Sets the custom name of the monster. You see the name over the monster. + If you want to disable the custom name, simply set an empty string. */ void SetCustomName(const AString & a_CustomName); /** Is the custom name of this monster always visible? If not, you only see the name when you sight the mob. */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8e1842ec1..9b64faf79 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -93,7 +93,7 @@ public: virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) = 0; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) = 0; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) = 0; virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index a66c64309..0b5e3de91 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -719,21 +719,13 @@ void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol125::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { cCSLock Lock(m_CSPacket); - AString PlayerName(a_Player.GetColor()); - PlayerName.append(a_Player.GetName()); - if (PlayerName.length() > 14) - { - PlayerName.erase(14); - } - PlayerName += cChatColor::White; - WriteByte ((unsigned char)PACKET_PLAYER_LIST_ITEM); - WriteString(PlayerName); + WriteString(a_PlayerName); WriteBool (a_IsOnline); - WriteShort (a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + WriteShort (a_Ping); Flush(); } @@ -792,7 +784,14 @@ void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); - WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + WriteString(a_Player.GetCustomName()); + } + else + { + WriteString(a_Player.GetName()); + } WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 1063777a2..9ab0adfcd 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -65,7 +65,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 5c58ab0ba..af3bc68ee 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -260,7 +260,14 @@ void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player) cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); - WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + WriteString(a_Player.GetCustomName()); + } + else + { + WriteString(a_Player.GetName()); + } WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index ed9812377..2ac1d0d0f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -865,14 +865,14 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol172::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteString(a_Player.GetName()); + Pkt.WriteString(a_PlayerName); Pkt.WriteBool(a_IsOnline); - Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + Pkt.WriteShort(a_Ping); } @@ -946,9 +946,16 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet - Pkt.WriteVarInt(a_Player.GetUniqueID()); + Pkt.WriteVarInt((UInt32) a_Player.GetUniqueID()); Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); - Pkt.WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + Pkt.WriteString(a_Player.GetCustomName()); + } + else + { + Pkt.WriteString(a_Player.GetName()); + } Pkt.WriteFPInt(a_Player.GetPosX()); Pkt.WriteFPInt(a_Player.GetPosY()); Pkt.WriteFPInt(a_Player.GetPosZ()); @@ -3075,7 +3082,14 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); - Pkt.WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + Pkt.WriteString(a_Player.GetCustomName()); + } + else + { + Pkt.WriteString(a_Player.GetName()); + } const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); Pkt.WriteVarInt(Properties.size()); diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index ccfa19eb6..eb64f6ad5 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -97,7 +97,7 @@ public: virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c831da251..d9cfc140a 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -487,10 +487,10 @@ void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_A -void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocolRecognizer::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { ASSERT(m_Protocol != NULL); - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index a05aeda70..95fcae1d3 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -100,7 +100,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/World.cpp b/src/World.cpp index 99e09c658..469606012 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2147,7 +2147,7 @@ void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src -void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude) +void cWorld::BroadcastPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2157,7 +2157,7 @@ void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, { continue; } - ch->SendPlayerListItem(a_Player, a_IsOnline); + ch->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } } @@ -2669,7 +2669,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) cClientHandle * ch = (*itr)->GetClientHandle(); if ((ch != NULL) && !ch->IsDestroyed()) { - a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), true); + a_DestPlayer->GetClientHandle()->SendPlayerListItem((*itr)->GetTabListName(), true, (*itr)->GetClientHandle()->GetPing()); } } } @@ -3209,13 +3209,17 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { AString PlayerName ((*itr)->GetName()); + if ((*itr)->HasCustomName()) + { + PlayerName = (*itr)->GetCustomName(); + } + AString::size_type Found = PlayerName.find(LastWord); // Try to find last word in playername - if (Found == AString::npos) { continue; // No match } - + UsernamesByWeight.push_back(std::make_pair(Found, PlayerName)); // Match! Store it with the position of the match as a weight } Lock.Unlock(); diff --git a/src/World.h b/src/World.h index 578c9682b..5f4466603 100644 --- a/src/World.h +++ b/src/World.h @@ -237,7 +237,7 @@ public: void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); -- cgit v1.2.3 From 079634d18cf63abad05db0fda9a4510aa75c0522 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 19:20:59 +0200 Subject: Added the new functions to APIDump. --- src/Entities/Player.h | 2 +- src/Mobs/Monster.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index da64bd64f..49380c776 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -401,7 +401,7 @@ public: /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); - /** Is a custom name for this player set? */ + /** Returns true if the player has a custom name. */ bool HasCustomName(void) const { return !m_CustomName.empty(); } /** Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string. */ diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index a777978f6..1d66d50e5 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -150,7 +150,7 @@ public: /** Returns true if the monster has a custom name. */ bool HasCustomName(void) const { return !m_CustomName.empty(); } - /** Gets the custom name of the monster. If no custom name is set, the function returns a empty string. */ + /** Gets the custom name of the monster. If no custom name is set, the function returns an empty string. */ const AString & GetCustomName(void) const { return m_CustomName; } /** Sets the custom name of the monster. You see the name over the monster. @@ -161,7 +161,7 @@ public: bool IsCustomNameAlwaysVisible(void) const { return m_CustomNameAlwaysVisible; } /** Sets the custom name visiblity of this monster. - If false, you only see the name when you sight the mob. If true, you always see the custom name. */ + If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name. */ void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible); /// Translates MobType enum to a string, empty string if unknown -- cgit v1.2.3 From 5c53608dd0e59d67a9aad5b03a58e1ff48d619b3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 19:34:58 +0200 Subject: Added CustomName saving. --- src/Mobs/Monster.cpp | 10 ++++++++-- src/WorldStorage/NBTChunkSerializer.cpp | 2 ++ src/WorldStorage/WSSAnvil.cpp | 13 +++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index a89fa32a3..b0b836dff 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -710,7 +710,10 @@ void cMonster::SetCustomName(const AString & a_CustomName) m_CustomName = a_CustomName.substr(0, 64); } - m_World->BroadcastEntityMetadata(*this); + if (m_World != NULL) + { + m_World->BroadcastEntityMetadata(*this); + } } @@ -720,7 +723,10 @@ void cMonster::SetCustomName(const AString & a_CustomName) void cMonster::SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible) { m_CustomNameAlwaysVisible = a_CustomNameAlwaysVisible; - m_World->BroadcastEntityMetadata(*this); + if (m_World != NULL) + { + m_World->BroadcastEntityMetadata(*this); + } } diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 68e541eba..1962d42ff 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -504,6 +504,8 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddFloat("", a_Monster->GetDropChanceBoots()); m_Writer.EndList(); m_Writer.AddByte("CanPickUpLoot", (char)a_Monster->CanPickUpLoot()); + m_Writer.AddString("CustomName", a_Monster->GetCustomName()); + m_Writer.AddByte("CustomNameVisible", (char)a_Monster->IsCustomNameAlwaysVisible()); switch (a_Monster->GetMobType()) { case cMonster::mtBat: diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index e79cc291d..5c155aeef 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2640,6 +2640,19 @@ bool cWSSAnvil::LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_Monster.SetCanPickUpLoot(CanPickUpLoot); } + int CustomNameTag = a_NBT.FindChildByName(a_TagIdx, "CustomName"); + if ((CustomNameTag > 0) && (a_NBT.GetType(CustomNameTag) == TAG_String)) + { + a_Monster.SetCustomName(a_NBT.GetString(CustomNameTag)); + } + + int CustomNameVisibleTag = a_NBT.FindChildByName(a_TagIdx, "CustomNameVisible"); + if ((CustomNameVisibleTag > 0) && (a_NBT.GetType(CustomNameVisibleTag) == TAG_Byte)) + { + bool CustomNameVisible = (a_NBT.GetByte(CustomNameVisibleTag) == 1); + a_Monster.SetCustomNameAlwaysVisible(CustomNameVisible); + } + return true; } -- cgit v1.2.3 From 017235e15ccdfca901d63793c5544626e730ec48 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 20:02:52 +0200 Subject: [WebAdmin] Code improvements. --- src/WebAdmin.cpp | 150 +++++++++++++++++++++++++++++++++---------------------- src/WebAdmin.h | 10 +++- 2 files changed, 99 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 35a6d401c..341c64236 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -131,7 +131,7 @@ bool cWebAdmin::Start(void) m_TemplateScript.RegisterAPILibs(); if (!m_TemplateScript.LoadFile(FILE_IO_PREFIX "webadmin/template.lua")) { - LOGERROR("Could not load WebAdmin template \"%s\". WebAdmin disabled!", FILE_IO_PREFIX "webadmin/template.lua"); + LOGWARN("Could not load WebAdmin template \"%s\". WebAdmin disabled!", FILE_IO_PREFIX "webadmin/template.lua"); m_TemplateScript.Close(); m_HTTPServer.Stop(); return false; @@ -348,6 +348,94 @@ void cWebAdmin::HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & +void cWebAdmin::HandleFileRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) +{ + AString FileURL = a_Request.GetURL(); + std::replace(FileURL.begin(), FileURL.end(), '\\', '/'); + + // Remove all leading backslashes: + if (FileURL[0] == '/') + { + size_t FirstCharToRead = FileURL.find_first_not_of('/'); + if (FirstCharToRead != AString::npos) + { + FileURL = FileURL.substr(FirstCharToRead); + } + } + + // Remove all "../" strings: + ReplaceString(FileURL, "../", ""); + + bool LoadedSuccessfull = false; + AString Content = "

404 Not Found

"; + AString Path = Printf(FILE_IO_PREFIX "webadmin/files/%s", FileURL.c_str()); + if (cFile::IsFile(Path)) + { + cFile File(Path, cFile::fmRead); + AString FileContent; + if (File.IsOpen() && (File.ReadRestOfFile(FileContent) != -1)) + { + LoadedSuccessfull = true; + Content = FileContent; + } + } + + // Find content type (The currently method is very bad. We should change it later) + AString ContentType = "text/html"; + size_t LastPointPosition = Path.find_last_of('.'); + if (LoadedSuccessfull && (LastPointPosition != AString::npos) && (LastPointPosition < Path.length())) + { + AString FileExtension = Path.substr(LastPointPosition + 1); + ContentType = GetContentTypeFromFileExt(FileExtension); + } + + // Send the response: + cHTTPResponse Resp; + Resp.SetContentType(ContentType); + a_Connection.Send(Resp); + a_Connection.Send(Content); + a_Connection.FinishResponse(); +} + + + + + +AString cWebAdmin::GetContentTypeFromFileExt(const AString & a_FileExtension) +{ + static bool IsInitialized = false; + static std::map ContentTypeMap; + if (!IsInitialized) + { + // Initialize the ContentTypeMap: + ContentTypeMap["png"] = "image/png"; + ContentTypeMap["fif"] = "image/fif"; + ContentTypeMap["gif"] = "image/gif"; + ContentTypeMap["jpeg"] = "image/jpeg"; + ContentTypeMap["jpg"] = "image/jpeg"; + ContentTypeMap["jpe"] = "image/jpeg"; + ContentTypeMap["tiff"] = "image/tiff"; + ContentTypeMap["ico"] = "image/ico"; + ContentTypeMap["csv"] = "image/comma-separated-values"; + ContentTypeMap["css"] = "text/css"; + ContentTypeMap["js"] = "text/javascript"; + ContentTypeMap["txt"] = "text/plain"; + ContentTypeMap["rtx"] = "text/richtext"; + ContentTypeMap["xml"] = "text/xml"; + } + + AString FileExtension = StrToLower(a_FileExtension); + if (ContentTypeMap.find(a_FileExtension) == ContentTypeMap.end()) + { + return "text/html"; + } + return ContentTypeMap[FileExtension]; +} + + + + + sWebAdminPage cWebAdmin::GetPage(const HTTPRequest & a_Request) { sWebAdminPage Page; @@ -414,6 +502,7 @@ AString cWebAdmin::GetDefaultPage(void) + AString cWebAdmin::GetBaseURL( const AString& a_URL) { return GetBaseURL(StringSplit(a_URL, "/")); @@ -560,64 +649,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & } else { - AString FileURL = URL; - std::replace(FileURL.begin(), FileURL.end(), '\\', '/'); - - // Remove all backsplashes on the first place: - if (FileURL[0] == '/') - { - size_t FirstCharToRead = FileURL.find_first_not_of('/'); - if (FirstCharToRead != AString::npos) - { - FileURL = FileURL.substr(FirstCharToRead); - } - } - - // Remove all "../" strings: - ReplaceString(FileURL, "../", ""); - - bool LoadedSuccessfull = false; - AString Content = "

404 Not Found

"; - AString Path = Printf(FILE_IO_PREFIX "webadmin/files/%s", FileURL.c_str()); - if (cFile::IsFile(Path)) - { - cFile File(Path, cFile::fmRead); - AString FileContent; - if (File.IsOpen() && (File.ReadRestOfFile(FileContent) != -1)) - { - LoadedSuccessfull = true; - Content = FileContent; - } - } - - // Find content type (The currently method is very bad. We should change it later) - AString ContentType = "text/html"; - size_t LastPointPosition = Path.find_last_of('.'); - if (LoadedSuccessfull && (LastPointPosition != AString::npos) && (LastPointPosition < Path.length())) - { - const AString & FileExtension = StrToLower(Path.substr(LastPointPosition + 1)); - if (FileExtension == "png") ContentType = "image/png"; - if (FileExtension == "fif") ContentType = "image/fif"; - if (FileExtension == "gif") ContentType = "image/gif"; - if (FileExtension == "jpeg") ContentType = "image/jpeg"; - if (FileExtension == "jpg") ContentType = "image/jpeg"; - if (FileExtension == "jpe") ContentType = "image/jpeg"; - if (FileExtension == "tiff") ContentType = "image/tiff"; - if (FileExtension == "ico") ContentType = "image/ico"; - if (FileExtension == "csv") ContentType = "text/comma-separated-values"; - if (FileExtension == "css") ContentType = "text/css"; - if (FileExtension == "js") ContentType = "text/javascript"; - if (FileExtension == "txt") ContentType = "text/plain"; - if (FileExtension == "rtx") ContentType = "text/richtext"; - if (FileExtension == "xml") ContentType = "text/xml"; - } - - // Send the response: - cHTTPResponse Resp; - Resp.SetContentType(ContentType); - a_Connection.Send(Resp); - a_Connection.Send(Content); - a_Connection.FinishResponse(); + HandleFileRequest(a_Connection, a_Request); } // Delete any request data assigned to the request: diff --git a/src/WebAdmin.h b/src/WebAdmin.h index a59c69096..d6baa2ef9 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -116,7 +116,7 @@ public: /** Stops the HTTP server, if it was started. */ void Stop(void); - /** Loads the login template. Returns true if the loading success, false if not. */ + /** Loads the login template. Returns true if the loading succeeds, false if not. */ bool LoadLoginTemplate(void); void AddPlugin(cWebPlugin * a_Plugin); @@ -149,6 +149,9 @@ public: /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ static AString GetBaseURL(const AStringVector & a_URLSplit); + /** Returns the content type from the file extension. If the extension isn't in the list, the function returns "text/html" */ + AString GetContentTypeFromFileExt(const AString & a_FileExtension); + protected: /** Common base class for request body data handlers */ class cRequestData @@ -208,7 +211,7 @@ protected: /** The Lua template script to provide templates: */ cLuaState m_TemplateScript; - /** The template who provide the login side: */ + /** The template that provides the login site: */ AString m_LoginTemplate; /** The HTTP server which provides the underlying HTTP parsing, serialization and events */ @@ -220,6 +223,9 @@ protected: /** Handles requests for the root page */ void HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); + /** Handles requests for a file */ + void HandleFileRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); + // cHTTPServer::cCallbacks overrides: virtual void OnRequestBegun (cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override; virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override; -- cgit v1.2.3 From 38e824dbcfa66ee63670f6e8aa708e7a4aa58f5e Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 20:10:41 +0200 Subject: Renamed SetWalkSpeed() to SetRelativeWalkSpeed() --- src/Entities/EntityEffect.cpp | 8 ++++---- src/Mobs/Monster.cpp | 4 ++-- src/Mobs/Monster.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 9cf20095d..1ebbf1926 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -240,7 +240,7 @@ void cEntityEffectSpeed::OnActivate(cPawn & a_Target) if (a_Target.IsMob()) { cMonster * Mob = (cMonster*) &a_Target; - Mob->SetWalkSpeed(Mob->GetWalkSpeed() + 0.2 * m_Intensity); + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() + 0.2 * m_Intensity); } else if (a_Target.IsPlayer()) { @@ -260,7 +260,7 @@ void cEntityEffectSpeed::OnDeactivate(cPawn & a_Target) if (a_Target.IsMob()) { cMonster * Mob = (cMonster*) &a_Target; - Mob->SetWalkSpeed(Mob->GetWalkSpeed() - 0.2 * m_Intensity); + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() - 0.2 * m_Intensity); } else if (a_Target.IsPlayer()) { @@ -283,7 +283,7 @@ void cEntityEffectSlowness::OnActivate(cPawn & a_Target) if (a_Target.IsMob()) { cMonster * Mob = (cMonster*) &a_Target; - Mob->SetWalkSpeed(Mob->GetWalkSpeed() - 0.15 * m_Intensity); + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() - 0.15 * m_Intensity); } else if (a_Target.IsPlayer()) { @@ -303,7 +303,7 @@ void cEntityEffectSlowness::OnDeactivate(cPawn & a_Target) if (a_Target.IsMob()) { cMonster * Mob = (cMonster*) &a_Target; - Mob->SetWalkSpeed(Mob->GetWalkSpeed() + 0.15 * m_Intensity); + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() + 0.15 * m_Intensity); } else if (a_Target.IsPlayer()) { diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 09a22cd35..7e40794b1 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -89,7 +89,7 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_DropChanceBoots(0.085f) , m_CanPickUpLoot(true) , m_BurnsInDaylight(false) - , m_WalkSpeed(1.0) + , m_RelativeWalkSpeed(1.0) { if (!a_ConfigName.empty()) { @@ -304,7 +304,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } // Apply walk speed: - Distance *= m_WalkSpeed; + Distance *= m_RelativeWalkSpeed; AddSpeedX(Distance.x); AddSpeedZ(Distance.z); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 6db8435e2..ca3c04c23 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -138,8 +138,8 @@ public: /// Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick void SetBurnsInDaylight(bool a_BurnsInDaylight) { m_BurnsInDaylight = a_BurnsInDaylight; } - double GetWalkSpeed(void) const { return m_WalkSpeed; } // tolua_export - void SetWalkSpeed(double a_WalkSpeed) { m_WalkSpeed = a_WalkSpeed; } // tolua_export + double GetRelativeWalkSpeed(void) const { return m_RelativeWalkSpeed; } // tolua_export + void SetRelativeWalkSpeed(double a_WalkSpeed) { m_RelativeWalkSpeed = a_WalkSpeed; } // tolua_export // Overridables to handle ageable mobs virtual bool IsBaby (void) const { return false; } @@ -251,7 +251,7 @@ protected: void HandleDaylightBurning(cChunk & a_Chunk); bool m_BurnsInDaylight; - double m_WalkSpeed; + double m_RelativeWalkSpeed; /** Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops*/ void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); -- cgit v1.2.3 From c19b2befa88bfe5549a3630c997070d5e1d37941 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 20:17:31 +0200 Subject: Changed the IsEnchantable() comment again. --- src/Item.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Item.h b/src/Item.h index e7fd67b9a..056b5eb8a 100644 --- a/src/Item.h +++ b/src/Item.h @@ -184,7 +184,8 @@ public: void FromJson(const Json::Value & a_Value); /** Returns true if the specified item type is enchantable. - If WithBook is true, the function checks the enchantments with a book too. */ + If WithBook is true, the function is used in the anvil inventory with book enchantments. + So it checks the "only book enchantments" too. Example: You can only enchant a hoe with a book. */ static bool IsEnchantable(short a_ItemType, bool a_WithBook = false); // tolua_export /** Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0 */ -- cgit v1.2.3 From 92a60bf4d5b0fe4705d9aa83e318f02d5ed2c0a0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 2 Sep 2014 22:40:24 +0200 Subject: Added strict error reporting to chunk loading. This should help with #1307. --- src/WorldStorage/WSSAnvil.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index e79cc291d..0c31d8b02 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -69,6 +69,18 @@ Since only the header is actually in the memory, this number can be high, but st /// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities #define CHUNK_INFLATE_MAX 256 KiB +#define LOAD_FAILED(CHX, CHZ) \ + { \ + const int RegionX = FAST_FLOOR_DIV(CHX, 32); \ + const int RegionZ = FAST_FLOOR_DIV(CHZ, 32); \ + LOGERROR("%s (%d): Loading chunk [%d, %d] from file r.%d.%d.mca failed. " \ + "The server will now abort in order to avoid further data loss. " \ + "Please add the reported file and this message to the issue report.", \ + __FUNCTION__, __LINE__, CHX, CHZ, RegionX, RegionZ \ + ); \ + *((int *)0) = 0; /* Crash intentionally */ \ + } + @@ -263,6 +275,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & inflateEnd(&strm); if (res != Z_STREAM_END) { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } @@ -271,6 +284,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & if (!NBT.IsValid()) { // NBT Parsing failed + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } @@ -317,11 +331,13 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT int Level = a_NBT.FindChildByName(0, "Level"); if (Level < 0) { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } int Sections = a_NBT.FindChildByName(Level, "Sections"); if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound)) { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child)) @@ -2811,30 +2827,42 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a } unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]); unsigned ChunkOffset = ChunkLocation >> 8; + if (ChunkOffset <= 2) + { + return false; + } m_File.Seek((int)ChunkOffset * 4096); int ChunkSize = 0; if (m_File.Read(&ChunkSize, 4) != 4) { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } ChunkSize = ntohl((u_long)ChunkSize); char CompressionType = 0; if (m_File.Read(&CompressionType, 1) != 1) { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } if (CompressionType != 2) { // Chunk is in an unknown compression + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } ChunkSize--; // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly a_Data.assign(ChunkSize, '\0'); - return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize); + if (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize) + { + return true; + } + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); + return false; } -- cgit v1.2.3 From a0687b42e44df65cf4774b40af59ad763c48fa1a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 2 Sep 2014 23:05:24 +0200 Subject: Clang wants volatile... --- src/WorldStorage/WSSAnvil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 0c31d8b02..815b6544f 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -78,7 +78,7 @@ Since only the header is actually in the memory, this number can be high, but st "Please add the reported file and this message to the issue report.", \ __FUNCTION__, __LINE__, CHX, CHZ, RegionX, RegionZ \ ); \ - *((int *)0) = 0; /* Crash intentionally */ \ + *((volatile int *)0) = 0; /* Crash intentionally */ \ } -- cgit v1.2.3 From a600e3bdfef5514d28475b6574f1c78ee74ed214 Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Wed, 3 Sep 2014 00:14:51 +0200 Subject: hopefully the last commit for removing y-coord from chunks. :) --- src/ChunkDef.h | 21 +++++++++++++++++++++ src/Generating/ChunkGenerator.cpp | 18 ++++++++++++------ src/Generating/ChunkGenerator.h | 10 +++++----- src/World.cpp | 13 ++----------- src/WorldStorage/WorldStorage.cpp | 2 +- 5 files changed, 41 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 111e081db..ded0bdf4c 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -389,6 +389,27 @@ typedef std::vector cChunkCoordsVector; +class cChunkCoordsWithBool +{ +public: + int m_ChunkX; + int m_ChunkZ; + bool m_ForceGenerate; + + cChunkCoordsWithBool(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), m_ForceGenerate(a_ForceGenerate){} + + bool operator == (const cChunkCoordsWithBool & a_Other) const + { + return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkZ == a_Other.m_ChunkZ) && (m_ForceGenerate == a_Other.m_ForceGenerate)); + } +}; + +typedef std::list cChunkCoordWithBoolList; + + + + + /// Interface class used as a callback for operations that involve chunk coords class cChunkCoordCallback { diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 845202358..6216958d2 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -99,13 +99,13 @@ void cChunkGenerator::Stop(void) -void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ) +void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate) { { cCSLock Lock(m_CS); // Check if it is already in the queue: - for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) + for (cChunkCoordWithBoolList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) { if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ)) { @@ -119,7 +119,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ) { LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (" SIZE_T_FMT ")", a_ChunkX, a_ChunkZ, m_Queue.size()); } - m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); + m_Queue.push_back(cChunkCoordsWithBool(a_ChunkX, a_ChunkZ, a_ForceGenerate)); } m_Event.Set(); @@ -229,8 +229,9 @@ void cChunkGenerator::Execute(void) continue; } - cChunkCoords coords = m_Queue.front(); // Get next coord from queue + cChunkCoordsWithBool coords = m_Queue.front(); // Get next coord from queue bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT); + m_Queue.erase(m_Queue.begin()); // Remove coordinate from queue Lock.Unlock(); // Unlock ASAP m_evtRemoved.Set(); @@ -244,6 +245,13 @@ void cChunkGenerator::Execute(void) LastReportTick = clock(); } + if (!coords.m_ForceGenerate && m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ)) + { + LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ); + // Already generated, ignore request + continue; + } + if (SkipEnabled && !m_ChunkSink->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkZ)) { LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ); @@ -253,8 +261,6 @@ void cChunkGenerator::Execute(void) LOGD("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ); DoGenerate(coords.m_ChunkX, coords.m_ChunkZ); - m_Queue.erase(m_Queue.begin()); // Remove coordinate from queue - NumChunksGenerated++; } // while (!bStop) } diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index 17ca8adce..0737834c9 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -116,7 +116,7 @@ public: void Stop(void); /// Queues the chunk for generation; removes duplicate requests - void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ); + void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate); /// Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); @@ -137,10 +137,10 @@ private: int m_Seed; - cCriticalSection m_CS; - cChunkCoordsList m_Queue; - cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate - cEvent m_evtRemoved; ///< Set when an item is removed from the queue + cCriticalSection m_CS; + cChunkCoordWithBoolList m_Queue; + cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate + cEvent m_evtRemoved; ///< Set when an item is removed from the queue cGenerator * m_Generator; ///< The actual generator engine used to generate chunks diff --git a/src/World.cpp b/src/World.cpp index f6fed53ee..2301cd8c6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2900,7 +2900,7 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) { m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ); - m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ); + m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ, true); } @@ -2909,16 +2909,7 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) { - /** Add a chunk to the generation queue, if it's not already present. */ - if (!(m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ))) - { - LOGD("Chunk [%d, %d] already generated, skipping generation", a_ChunkX, a_ChunkZ); - /** Already generated, ignore request */ - } - else - { - m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ); - } + m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ, false); } diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index c4df8c379..0d7698b3d 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -249,7 +249,7 @@ bool cWorldStorage::LoadOneChunk(void) if (ToLoad.m_Generate) { // The chunk couldn't be loaded, generate it: - m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ); + m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ, true); } else { -- cgit v1.2.3 From 554f58501733f00f54e88190bc8ad85bfb11b84f Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Wed, 3 Sep 2014 00:28:08 +0200 Subject: re-add the missing "s" too cChunkCoordsWithBoolList --- src/ChunkDef.h | 2 +- src/Generating/ChunkGenerator.cpp | 2 +- src/Generating/ChunkGenerator.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ChunkDef.h b/src/ChunkDef.h index ded0bdf4c..7247cf5e4 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -404,7 +404,7 @@ public: } }; -typedef std::list cChunkCoordWithBoolList; +typedef std::list cChunkCoordsWithBoolList; diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 6216958d2..d39b44733 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -105,7 +105,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_Forc cCSLock Lock(m_CS); // Check if it is already in the queue: - for (cChunkCoordWithBoolList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) + for (cChunkCoordsWithBoolList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr) { if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ)) { diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index 0737834c9..e880a6766 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -137,10 +137,10 @@ private: int m_Seed; - cCriticalSection m_CS; - cChunkCoordWithBoolList m_Queue; - cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate - cEvent m_evtRemoved; ///< Set when an item is removed from the queue + cCriticalSection m_CS; + cChunkCoordsWithBoolList m_Queue; + cEvent m_Event; ///< Set when an item is added to the queue or the thread should terminate + cEvent m_evtRemoved; ///< Set when an item is removed from the queue cGenerator * m_Generator; ///< The actual generator engine used to generate chunks -- cgit v1.2.3 From 5a608dc2794aa83ab687db5ae692c2d702729668 Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Wed, 3 Sep 2014 02:53:21 +0200 Subject: adapting format --- src/Generating/BioGen.cpp | 7 ++++--- src/Generating/BioGen.h | 8 ++++++-- src/Generating/ComposableGenerator.cpp | 6 ++++-- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 69af5c79a..46516b327 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -212,11 +212,12 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) // cBioGenMulticache: cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) : -m_CachesLength(a_CachesLength), -m_InternalCacheLength(a_CachesLength * a_CacheSize) + m_CachesLength(a_CachesLength), + m_InternalCacheLength(a_CachesLength * a_CacheSize) { m_Caches.reserve(m_InternalCacheLength); - for (size_t i = 0; i < m_InternalCacheLength; i++) { + for (size_t i = 0; i < m_InternalCacheLength; i++) + { m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); } } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index cfa748ec7..47383633f 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -87,12 +87,16 @@ class cBioGenMulticache : typedef cBiomeGen super; public: + /* + a_CacheSize defines the size of each singular cache + a_CachesLength defines how many caches are used for the multicache + */ cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache ~cBioGenMulticache(); protected: - size_t m_CachesLength; - size_t m_InternalCacheLength; + size_t m_CachesLength; + size_t m_InternalCacheLength; // used internally only std::vector m_Caches; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 0535e89f3..d70438bf3 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -243,11 +243,13 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) } LOGD("Using a cache for biomegen of size %d.", CacheSize); m_UnderlyingBiomeGen = m_BiomeGen; - if (MultiCacheLength > 0) { + if (MultiCacheLength > 0) + { LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); } - else { + else + { m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); } -- cgit v1.2.3 From b414e918833999ae0c2b11cefd864ad3c07fc18f Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 2 Sep 2014 22:56:39 -0700 Subject: EntityEffect.cpp: Enable 1.8's leaping potion --- src/Entities/EntityEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 3e28392f4..a33955a6a 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -34,6 +34,7 @@ cEntityEffect::eType cEntityEffect::GetPotionEffectType(short a_ItemDamage) case 0x08: return cEntityEffect::effWeakness; case 0x09: return cEntityEffect::effStrength; case 0x0a: return cEntityEffect::effSlowness; + case 0x0b: return cEntityEffect::effJumpBoost; case 0x0c: return cEntityEffect::effInstantDamage; case 0x0d: return cEntityEffect::effWaterBreathing; case 0x0e: return cEntityEffect::effInvisibility; @@ -41,7 +42,6 @@ cEntityEffect::eType cEntityEffect::GetPotionEffectType(short a_ItemDamage) // No effect potions case 0x00: case 0x07: - case 0x0b: // Will be potion of leaping in 1.8 case 0x0f: { break; -- cgit v1.2.3 From 34d6f0713e94b5cb3424be6ed3374afaeca5526b Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 2 Sep 2014 23:21:08 -0700 Subject: Added mutton, which sheep now drop when killed --- src/BlockID.h | 2 ++ src/Items/ItemFood.h | 2 ++ src/Items/ItemHandler.cpp | 2 ++ src/Mobs/Sheep.cpp | 7 +++++++ 4 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 08c576886..1565fee49 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -362,6 +362,8 @@ enum ENUM_ITEM_ID E_ITEM_LEAD = 420, E_ITEM_NAME_TAG = 421, E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422, + E_ITEM_RAW_MUTTON = 423, + E_ITEM_MUTTON = 424, // Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++ // IsValidItem() depends on this! diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 98050cad8..c7e7ef2ca 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -47,10 +47,12 @@ public: case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2); case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2); case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8); + case E_ITEM_RAW_MUTTON: return FoodInfo(2, 1.2); case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8); case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2); case E_ITEM_STEAK: return FoodInfo(8, 12.8); + case E_ITEM_MUTTON: return FoodInfo(6, 9.6); } LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType); return FoodInfo(0, 0.f); diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index bceedaf69..45a779ade 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -223,10 +223,12 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_RAW_CHICKEN: case E_ITEM_RAW_FISH: case E_ITEM_RAW_PORKCHOP: + case E_ITEM_RAW_MUTTON: case E_ITEM_RED_APPLE: case E_ITEM_ROTTEN_FLESH: case E_ITEM_SPIDER_EYE: case E_ITEM_STEAK: + case E_ITEM_MUTTON: { return new cItemFoodHandler(a_ItemType); } diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 9fb47201d..3be688b43 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -39,6 +39,13 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) { a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, m_WoolColor)); } + + int LootingLevel = 0; + if (a_Killer != NULL) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_MUTTON : E_ITEM_RAW_MUTTON); } -- cgit v1.2.3 From 1cc65b626462ca3e5aff1619e51450b5d33ff717 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 10:29:10 +0200 Subject: Fixed style and alpha-sorting. --- src/BlockID.h | 4 ++-- src/Entities/Entity.cpp | 4 ++-- src/Entities/EntityEffect.cpp | 4 ++-- src/Items/ItemFood.h | 6 +++--- src/Items/ItemHandler.cpp | 8 ++++---- src/Mobs/Sheep.cpp | 14 +++++++------- 6 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 1565fee49..d835f9518 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -362,8 +362,8 @@ enum ENUM_ITEM_ID E_ITEM_LEAD = 420, E_ITEM_NAME_TAG = 421, E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422, - E_ITEM_RAW_MUTTON = 423, - E_ITEM_MUTTON = 424, + E_ITEM_RAW_MUTTON = 423, + E_ITEM_MUTTON = 424, // Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++ // IsValidItem() depends on this! diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 89d1cffa1..9bcdcffeb 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -387,7 +387,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtGhast: case cMonster::mtZombiePigman: case cMonster::mtMagmaCube: - { + { break; }; default: StartBurning(BurnTicks * 20); @@ -417,7 +417,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } if (!Player->IsOnGround()) - { + { if ((a_TDI.DamageType == dtAttack) || (a_TDI.DamageType == dtArrowAttack)) { a_TDI.FinalDamage += 2; diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index a33955a6a..f08755674 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -34,11 +34,11 @@ cEntityEffect::eType cEntityEffect::GetPotionEffectType(short a_ItemDamage) case 0x08: return cEntityEffect::effWeakness; case 0x09: return cEntityEffect::effStrength; case 0x0a: return cEntityEffect::effSlowness; - case 0x0b: return cEntityEffect::effJumpBoost; + case 0x0b: return cEntityEffect::effJumpBoost; case 0x0c: return cEntityEffect::effInstantDamage; case 0x0d: return cEntityEffect::effWaterBreathing; case 0x0e: return cEntityEffect::effInvisibility; - + // No effect potions case 0x00: case 0x07: diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index c7e7ef2ca..8bea19fba 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -43,16 +43,16 @@ public: case E_ITEM_POISONOUS_POTATO: return FoodInfo(2, 1.2); // Potatoes handled in ItemSeeds case E_ITEM_PUMPKIN_PIE: return FoodInfo(8, 4.8); + case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8); case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2); case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2); + case E_ITEM_RAW_MUTTON: return FoodInfo(2, 1.2); case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8); - case E_ITEM_RAW_MUTTON: return FoodInfo(2, 1.2); - case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8); case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2); case E_ITEM_STEAK: return FoodInfo(8, 12.8); - case E_ITEM_MUTTON: return FoodInfo(6, 9.6); + case E_ITEM_MUTTON: return FoodInfo(6, 9.6); } LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType); return FoodInfo(0, 0.f); diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 45a779ade..67c945ce4 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -207,7 +207,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) } // Food (please keep alpha-sorted): - // (carrots and potatoes handled in SeedHandler as both seed and food + // (carrots and potatoes handled separately in SeedHandler as they're both seed and food) case E_ITEM_BAKED_POTATO: case E_ITEM_BREAD: case E_ITEM_COOKED_CHICKEN: @@ -217,18 +217,18 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_GOLDEN_CARROT: case E_ITEM_MELON_SLICE: case E_ITEM_MUSHROOM_SOUP: + case E_ITEM_MUTTON: case E_ITEM_POISONOUS_POTATO: case E_ITEM_PUMPKIN_PIE: + case E_ITEM_RED_APPLE: case E_ITEM_RAW_BEEF: case E_ITEM_RAW_CHICKEN: case E_ITEM_RAW_FISH: + case E_ITEM_RAW_MUTTON: case E_ITEM_RAW_PORKCHOP: - case E_ITEM_RAW_MUTTON: - case E_ITEM_RED_APPLE: case E_ITEM_ROTTEN_FLESH: case E_ITEM_SPIDER_EYE: case E_ITEM_STEAK: - case E_ITEM_MUTTON: { return new cItemFoodHandler(a_ItemType); } diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 3be688b43..1a82115d2 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -39,13 +39,13 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) { a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, m_WoolColor)); } - - int LootingLevel = 0; - if (a_Killer != NULL) - { - LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); - } - AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_MUTTON : E_ITEM_RAW_MUTTON); + + int LootingLevel = 0; + if (a_Killer != NULL) + { + LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + } + AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_MUTTON : E_ITEM_RAW_MUTTON); } -- cgit v1.2.3 From 42fb71f261519dbb6c417aefea626d01eadf8abb Mon Sep 17 00:00:00 2001 From: LO1ZB Date: Wed, 3 Sep 2014 13:52:32 +0200 Subject: commit --- src/WorldStorage/WorldStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 0d7698b3d..667a28470 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -249,7 +249,7 @@ bool cWorldStorage::LoadOneChunk(void) if (ToLoad.m_Generate) { // The chunk couldn't be loaded, generate it: - m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ, true); + m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ, false); } else { -- cgit v1.2.3 From 9eb07f483a237f3fba21a761e7a19053032d2282 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 16:56:59 +0200 Subject: cBoundingBox: Added accessors. --- src/BoundingBox.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/BoundingBox.h b/src/BoundingBox.h index 793466302..928e62afa 100644 --- a/src/BoundingBox.h +++ b/src/BoundingBox.h @@ -80,6 +80,17 @@ public: /// Calculates the intersection of the two bounding boxes; returns true if nonempty bool Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection); + double GetMinX(void) const { return m_Min.x; } + double GetMinY(void) const { return m_Min.y; } + double GetMinZ(void) const { return m_Min.z; } + + double GetMaxX(void) const { return m_Max.x; } + double GetMaxY(void) const { return m_Max.y; } + double GetMaxZ(void) const { return m_Max.z; } + + const Vector3d & GetMin(void) const { return m_Min; } + const Vector3d & GetMax(void) const { return m_Max; } + protected: Vector3d m_Min; Vector3d m_Max; -- cgit v1.2.3 From a51c1e0b73a83cddcce865671ca30240393e458f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 17:00:26 +0200 Subject: Added cWorld::ForEachEntityInBox() --- src/Bindings/LuaState.cpp | 26 ++++++++++++++++++++++++++ src/Bindings/LuaState.h | 10 ++++++++++ src/Chunk.cpp | 25 +++++++++++++++++++++++++ src/Chunk.h | 4 ++++ src/ChunkMap.cpp | 32 ++++++++++++++++++++++++++++++++ src/ChunkMap.h | 6 ++++++ src/World.cpp | 9 +++++++++ src/World.h | 5 +++++ 8 files changed, 117 insertions(+) (limited to 'src') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 9fe93ccc2..4ebb1e92f 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -859,6 +859,32 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) +{ + tolua_Error err; + if (tolua_isusertable(m_LuaState, a_StackPos, "cBoundingBox", false, &err)) + { + a_ReturnedVal = (cBoundingBox *)lua_touserdata(m_LuaState, a_StackPos); + } +} + + + + + +void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal) +{ + tolua_Error err; + if (tolua_isusertable(m_LuaState, a_StackPos, "cWorld", false, &err)) + { + a_ReturnedVal = (cWorld *)lua_touserdata(m_LuaState, a_StackPos); + } +} + + + + + bool cLuaState::CallFunction(int a_NumResults) { ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index eeb93fd4d..fd506b10e 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -59,6 +59,10 @@ class cTNTEntity; class cCreeper; class cHopperEntity; class cBlockEntity; +class cBoundingBox; + +typedef cBoundingBox * pBoundingBox; +typedef cWorld * pWorld; @@ -230,6 +234,12 @@ public: /** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather. If not, a_Value is unchanged. */ void GetStackValue(int a_StackPos, eWeather & a_Value); + + /** Retrieve value at a_StackPos, if it is a valid cBoundingBox class. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, pBoundingBox & a_Value); + + /** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, pWorld & a_Value); // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 40ffff834..20e943d9a 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -37,6 +37,7 @@ #include "MobSpawner.h" #include "BlockInServerPluginInterface.h" #include "SetChunkData.h" +#include "BoundingBox.h" #include "json/json.h" @@ -1960,6 +1961,30 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback) +bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) +{ + // The entity list is locked by the parent chunkmap's CS + for (cEntityList::iterator itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) + { + ++itr2; + cBoundingBox EntBox((*itr)->GetPosition(), (*itr)->GetWidth() / 2, (*itr)->GetHeight()); + if (!EntBox.DoesIntersect(a_Box)) + { + // The entity is not in the specified box + continue; + } + if (a_Callback.Item(*itr)) + { + return false; + } + } // for itr - m_Entitites[] + return true; +} + + + + + bool cChunk::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult) { // The entity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index e5de22e3b..008a351db 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -216,6 +216,10 @@ public: /** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible + /** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox. + Returns true if all entities processed, false if the callback aborted by returning true. */ + bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible + /** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */ bool DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult); // Lua-accessible diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index a3692ef11..ffc5e3d3f 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1775,6 +1775,38 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback +bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) +{ + // Calculate the chunk range for the box: + int MinChunkX = (int)floor(a_Box.GetMinX() / cChunkDef::Width); + int MinChunkZ = (int)floor(a_Box.GetMinZ() / cChunkDef::Width); + int MaxChunkX = (int)floor((a_Box.GetMaxX() + cChunkDef::Width) / cChunkDef::Width); + int MaxChunkZ = (int)floor((a_Box.GetMaxZ() + cChunkDef::Width) / cChunkDef::Width); + + // Iterate over each chunk in the range: + cCSLock Lock(m_CSLayers); + for (int z = MinChunkZ; z <= MaxChunkZ; z++) + { + for (int x = MinChunkX; x <= MaxChunkX; x++) + { + cChunkPtr Chunk = GetChunkNoGen(x, ZERO_CHUNK_Y, z); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + if (!Chunk->ForEachEntityInBox(a_Box, a_Callback)) + { + return false; + } + } // for x + } // for z + return true; +} + + + + + void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected) { // Don't explode if outside of Y range (prevents the following test running into unallocated memory): diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 1e9a0f982..24a91dcd1 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -36,6 +36,7 @@ class cBlockArea; class cMobCensus; class cMobSpawner; class cSetChunkData; +class cBoundingBox; typedef std::list cClientHandleList; typedef cChunk * cChunkPtr; @@ -209,6 +210,11 @@ public: /** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible + /** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox. + Returns true if all entities processed, false if the callback aborted by returning true. + If any chunk in the box is missing, ignores the entities in that chunk silently. */ + bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible + /** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */ void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected); diff --git a/src/World.cpp b/src/World.cpp index 99e09c658..d3751364f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2696,6 +2696,15 @@ bool cWorld::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & +bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) +{ + return m_ChunkMap->ForEachEntityInBox(a_Box, a_Callback); +} + + + + + bool cWorld::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback) { return m_ChunkMap->DoWithEntityByID(a_UniqueID, a_Callback); diff --git a/src/World.h b/src/World.h index 578c9682b..d4acb52d4 100644 --- a/src/World.h +++ b/src/World.h @@ -324,6 +324,11 @@ public: /** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp + /** Calls the callback for each entity that has a nonempty intersection with the specified boundingbox. + Returns true if all entities processed, false if the callback aborted by returning true. + If any chunk in the box is missing, ignores the entities in that chunk silently. */ + bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp + /** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. */ bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp -- cgit v1.2.3 From a9ed5baba35b012f577ca6c6cca970042fc4edf0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 17:01:23 +0200 Subject: Exported ForEachEntityInBox() to Lua API. --- src/Bindings/ManualBindings.cpp | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index adf10a72f..b7ea65759 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -676,6 +676,75 @@ static int tolua_ForEachInChunk(lua_State * tolua_S) +template < + class Ty1, + class Ty2, + bool (Ty1::*Func1)(const cBoundingBox &, cItemCallback &) +> +static int tolua_ForEachInBox(lua_State * tolua_S) +{ + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cWorld") || + !L.CheckParamUserType(2, "cBoundingBox") || + !L.CheckParamFunction(3) || + !L.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + Ty1 * Self = NULL; + cBoundingBox * Box = NULL; + L.GetStackValues(1, Self, Box); + ASSERT(Self != NULL); // We have verified the type at the top, so we should get valid objects here + ASSERT(Box != NULL); + + // Create a reference for the function: + cLuaState::cRef FnRef(L, 3); + + // Callback wrapper for the Lua function: + class cLuaCallback : public cItemCallback + { + public: + cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) : + m_LuaState(a_LuaState), + m_FnRef(a_FuncRef) + {} + + private: + // cItemCallback overrides: + virtual bool Item(Ty2 * a_Item) override + { + bool res = false; + if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res)) + { + LOGWARNING("Failed to call Lua callback"); + m_LuaState.LogStackTrace(); + return true; // Abort enumeration + } + + return res; + } + cLuaState & m_LuaState; + cLuaState::cRef & m_FnRef; + } Callback(L, FnRef); + + bool bRetVal = (Self->*Func1)(*Box, Callback); + + FnRef.UnRef(); + + /* Push return value on stack */ + tolua_pushboolean(tolua_S, bRetVal); + return 1; +} + + + + + template < class Ty1, class Ty2, @@ -3327,6 +3396,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); + tolua_function(tolua_S, "ForEachEntityInBox", tolua_ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>); tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); -- cgit v1.2.3 From d2bacc34f6b4e9b0d7a6db9ba81d76c51b1fd60f Mon Sep 17 00:00:00 2001 From: DayBr3ak Date: Wed, 3 Sep 2014 18:48:47 +0200 Subject: change to linear calculation --- src/Generating/BioGen.cpp | 13 ++++++------- src/Generating/BioGen.h | 3 +-- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 46516b327..175e4ef33 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -151,7 +151,7 @@ void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses)); LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits); } - + for (int i = 0; i < m_CacheSize; i++) { if ( @@ -212,11 +212,10 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile) // cBioGenMulticache: cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) : - m_CachesLength(a_CachesLength), - m_InternalCacheLength(a_CachesLength * a_CacheSize) + m_CachesLength(a_CachesLength) { - m_Caches.reserve(m_InternalCacheLength); - for (size_t i = 0; i < m_InternalCacheLength; i++) + m_Caches.reserve(a_CachesLength); + for (size_t i = 0; i < a_CachesLength; i++) { m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); } @@ -240,8 +239,8 @@ cBioGenMulticache::~cBioGenMulticache() void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - size_t cacheIdx = ((size_t)a_ChunkX % m_CachesLength) * m_CachesLength - + ((size_t)a_ChunkZ % m_CachesLength); + const size_t coefficient = 3; + const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_CachesLength; m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index 47383633f..a4cf95a72 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -95,8 +95,7 @@ public: ~cBioGenMulticache(); protected: - size_t m_CachesLength; - size_t m_InternalCacheLength; // used internally only + size_t m_CachesLength; std::vector m_Caches; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -- cgit v1.2.3 From 44c1d9c2480fe6ea37dbed6199b51acf035de0c2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 19:36:53 +0200 Subject: Anvil: switched inflate to stream mode. This removes the fixed-size buffer which could have caused #1307 and #1366. --- src/StringCompression.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++ src/StringCompression.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 24 +++++------------ 3 files changed, 70 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/StringCompression.cpp b/src/StringCompression.cpp index 71d64e71e..af9f1687f 100644 --- a/src/StringCompression.cpp +++ b/src/StringCompression.cpp @@ -180,3 +180,65 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & + +extern int InflateString(const char * a_Data, size_t a_Length, AString & a_Uncompressed) +{ + a_Uncompressed.reserve(a_Length); + + char Buffer[64 KiB]; + z_stream strm; + memset(&strm, 0, sizeof(strm)); + strm.next_in = (Bytef *)a_Data; + strm.avail_in = (uInt)a_Length; + strm.next_out = (Bytef *)Buffer; + strm.avail_out = sizeof(Buffer); + + int res = inflateInit(&strm); // Force GZIP decoding + if (res != Z_OK) + { + LOG("%s: inflation initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg); + return res; + } + + for (;;) + { + res = inflate(&strm, Z_NO_FLUSH); + switch (res) + { + case Z_OK: + { + // Some data has been uncompressed. Consume the buffer and continue uncompressing + a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + strm.next_out = (Bytef *)Buffer; + strm.avail_out = sizeof(Buffer); + if (strm.avail_in == 0) + { + // All data has been uncompressed + inflateEnd(&strm); + return Z_OK; + } + break; + } + + case Z_STREAM_END: + { + // Finished uncompressing. Consume the rest of the buffer and return + a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + inflateEnd(&strm); + return Z_OK; + } + + default: + { + // An error has occurred, log it and return the error value + LOG("%s: inflation failed: %d (\"%s\").", __FUNCTION__, res, strm.msg); + inflateEnd(&strm); + return res; + } + } // switch (res) + } // while (true) +} + + + + diff --git a/src/StringCompression.h b/src/StringCompression.h index 038240797..dde17ce30 100644 --- a/src/StringCompression.h +++ b/src/StringCompression.h @@ -21,5 +21,7 @@ extern int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_ /// Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Uncompressed); +/** Uncompresses a_Data into a_Uncompressed using Inflate; returns Z_OK for success or Z_XXX error constants same as zlib */ +extern int InflateString(const char * a_Data, size_t a_Length, AString & a_Uncompressed); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 815b6544f..239f4a155 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -66,9 +66,6 @@ Since only the header is actually in the memory, this number can be high, but st */ #define MAX_MCA_FILES 32 -/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities -#define CHUNK_INFLATE_MAX 256 KiB - #define LOAD_FAILED(CHX, CHZ) \ { \ const int RegionX = FAST_FLOOR_DIV(CHX, 32); \ @@ -260,27 +257,18 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data) { - // Decompress the data: - char Uncompressed[CHUNK_INFLATE_MAX]; - z_stream strm; - strm.zalloc = (alloc_func)NULL; - strm.zfree = (free_func)NULL; - strm.opaque = NULL; - inflateInit(&strm); - strm.next_out = (Bytef *)Uncompressed; - strm.avail_out = sizeof(Uncompressed); - strm.next_in = (Bytef *)a_Data.data(); - strm.avail_in = (uInt)a_Data.size(); - int res = inflate(&strm, Z_FINISH); - inflateEnd(&strm); - if (res != Z_STREAM_END) + // Uncompress the data: + AString Uncompressed; + int res = InflateString(a_Data.data(), a_Data.size(), Uncompressed); + if (res != Z_OK) { + LOGWARNING("Uncompressing chunk [%d, %d] failed: %d", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, res); LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } // Parse the NBT data: - cParsedNBT NBT(Uncompressed, strm.total_out); + cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) { // NBT Parsing failed -- cgit v1.2.3 From bae928fd27cb26ec55db04f64d8de888443d65a0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 23:02:00 +0200 Subject: ChunkGenerator: Log world seed when creating a new one. --- src/Generating/ChunkGenerator.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index d39b44733..4fa9729ec 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -52,10 +52,21 @@ bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a m_PluginInterface = &a_PluginInterface; m_ChunkSink = &a_ChunkSink; - MTRand rnd; - m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", (int)rnd.randInt()); + // Get the seed; create a new one and log it if not found in the INI file: + if (a_IniFile.HasValue("Seed", "Seed")) + { + m_Seed = a_IniFile.GetValueI("Seed", "Seed"); + } + else + { + MTRand rnd; + m_Seed = rnd.randInt(); + LOGINFO("Chosen a new random seed for world: %d", m_Seed); + a_IniFile.SetValueI("Seed", "Seed", m_Seed); + } + + // Get the generator engine based on the INI file settings: AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); - if (NoCaseCompare(GeneratorName, "Noise3D") == 0) { m_Generator = new cNoise3DGenerator(*this); -- cgit v1.2.3 From 06c66a08cdbfbbac56d79a175bcc6142d690cc94 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 23:05:03 +0200 Subject: LuaState: Fixed referenced function pushing. The references are no longer destroyed by the call. --- src/Bindings/LuaState.h | 8 ++++++++ src/Bindings/gen_LuaState_Call.lua | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index fd506b10e..44f187701 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -338,6 +338,14 @@ protected: */ bool PushFunction(int a_FnRef); + /** Pushes a function that has been saved as a reference. + Returns true if successful. Logs a warning on failure + */ + bool PushFunction(const cRef & a_FnRef) + { + return PushFunction((int)a_FnRef); + } + /** Pushes a function that is stored in a referenced table by name Returns true if successful. Logs a warning on failure */ diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua index 2d8630d12..7f62573c7 100644 --- a/src/Bindings/gen_LuaState_Call.lua +++ b/src/Bindings/gen_LuaState_Call.lua @@ -109,7 +109,7 @@ local function WriteOverload(f, a_NumParams, a_NumReturns) -- Write the function signature: f:write("bool Call(") - f:write("FnT a_Function") + f:write("const FnT & a_Function") for i = 1, a_NumParams do f:write(", ParamT", i, " a_Param", i) end -- cgit v1.2.3 From 014a55a15ac77d274538236228ec990be9269080 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 3 Sep 2014 23:05:22 +0200 Subject: LuaState: Fixed class value-getting off the stack. --- src/Bindings/LuaState.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 4ebb1e92f..ba2f3c5e0 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -862,9 +862,9 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal) void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) { tolua_Error err; - if (tolua_isusertable(m_LuaState, a_StackPos, "cBoundingBox", false, &err)) + if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err)) { - a_ReturnedVal = (cBoundingBox *)lua_touserdata(m_LuaState, a_StackPos); + a_ReturnedVal = *((cBoundingBox **)lua_touserdata(m_LuaState, a_StackPos)); } } @@ -875,9 +875,9 @@ void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal) { tolua_Error err; - if (tolua_isusertable(m_LuaState, a_StackPos, "cWorld", false, &err)) + if (tolua_isusertype(m_LuaState, a_StackPos, "cWorld", false, &err)) { - a_ReturnedVal = (cWorld *)lua_touserdata(m_LuaState, a_StackPos); + a_ReturnedVal = *((cWorld **)lua_touserdata(m_LuaState, a_StackPos)); } } -- cgit v1.2.3 From 157f1c6688db8abe72c93a292f43d5a04040e0a4 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 4 Sep 2014 00:29:36 +0200 Subject: Started implementing of the 1.8 protocol. --- src/Protocol/CMakeLists.txt | 2 + src/Protocol/Protocol17x.cpp | 6 +- src/Protocol/Protocol17x.h | 14 +- src/Protocol/Protocol18x.cpp | 385 ++++++++++++++++++++++++++++++++++++ src/Protocol/Protocol18x.h | 76 +++++++ src/Protocol/ProtocolRecognizer.cpp | 25 ++- src/Protocol/ProtocolRecognizer.h | 1 + 7 files changed, 502 insertions(+), 7 deletions(-) create mode 100644 src/Protocol/Protocol18x.cpp create mode 100644 src/Protocol/Protocol18x.h (limited to 'src') diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt index 1ba66ff1f..5426c58fa 100644 --- a/src/Protocol/CMakeLists.txt +++ b/src/Protocol/CMakeLists.txt @@ -14,6 +14,7 @@ SET (SRCS Protocol15x.cpp Protocol16x.cpp Protocol17x.cpp + Protocol18x.cpp ProtocolRecognizer.cpp) SET (HDRS @@ -27,6 +28,7 @@ SET (HDRS Protocol15x.h Protocol16x.h Protocol17x.h + Protocol18x.h ProtocolRecognizer.h) if(NOT MSVC) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 1091b877f..00b115c8f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1,10 +1,12 @@ + // Protocol17x.cpp /* Implements the 1.7.x protocol classes: - cProtocol172 - release 1.7.2 protocol (#4) -(others may be added later in the future for the 1.7 release series) + - cProtocol176 + - release 1.7.6 protocol (#5) */ #include "Globals.h" @@ -1710,7 +1712,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp); - + cPacketizer Pkt(*this, 0x01); // Ping packet Pkt.WriteInt64(Timestamp); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index ccfa19eb6..ec948e8a1 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -5,7 +5,8 @@ Declares the 1.7.x protocol classes: - cProtocol172 - release 1.7.2 protocol (#4) -(others may be added later in the future for the 1.7 release series) + - cProtocol176 + - release 1.7.6 protocol (#5) */ @@ -198,6 +199,11 @@ protected: { m_Out.WriteVarUTF8String(a_Value); } + + void WritePosition(const Vector3i a_Position) + { + WriteInt64(((Int64)a_Position.x & 0x3FFFFFF) << 38 | ((Int64)a_Position.y & 0xFFF) << 26 | ((Int64)a_Position.z & 0x3FFFFFF)); + } void WriteBuf(const char * a_Data, size_t a_Size) { @@ -258,12 +264,12 @@ protected: bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType); // Packet handlers while in the Status state (m_State == 1): - void HandlePacketStatusPing (cByteBuffer & a_ByteBuffer); + void HandlePacketStatusPing(cByteBuffer & a_ByteBuffer); virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer); // Packet handlers while in the Login state (m_State == 2): - void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); - void HandlePacketLoginStart (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); + virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); // Packet handlers while in the Game state (m_State == 3): void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp new file mode 100644 index 000000000..0a455c70e --- /dev/null +++ b/src/Protocol/Protocol18x.cpp @@ -0,0 +1,385 @@ + +// Protocol18x.cpp + +/* +Implements the 1.8.x protocol classes: + - cProtocol180 + - release 1.8.0 protocol (#47) +(others may be added later in the future for the 1.8 release series) +*/ + +#include "Globals.h" +#include "Bindings/PluginManager.h" +#include "json/json.h" +#include "Protocol18x.h" + +#include "../ClientHandle.h" +#include "../CompositeChat.h" +#include "../Root.h" +#include "../Server.h" +#include "../World.h" + +#include "../Entities/Player.h" + +class cProtocol176; + + + + + +const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cProtocol180: + +cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : + super(a_Client, a_ServerAddress, a_ServerPort, a_State) +{ +} + + + + + +void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x23); // Block Change packet + Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + + UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15); + Pkt.WriteVarInt(Block); +} + + + + + +void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x22); // Multi Block Change packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteVarInt((UInt32)a_Changes.size()); + for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) + { + short Coords = itr->y | (itr->z << 8) | (itr->x << 12); + Pkt.WriteShort(Coords); + + UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15); + Pkt.WriteVarInt(Block); + } // for itr - a_Changes[] +} + + + + + +void cProtocol180::SendChat(const AString & a_Message) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x02); // Chat Message packet + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); + Pkt.WriteChar(0); +} + + + + + +void cProtocol180::SendChat(const cCompositeChat & a_Message) +{ + ASSERT(m_State == 3); // In game mode? + + // Compose the complete Json string to send: + Json::Value msg; + cWorld * World = m_Client->GetPlayer()->GetWorld(); + msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present + const cCompositeChat::cParts & Parts = a_Message.GetParts(); + for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) + { + Json::Value Part; + switch ((*itr)->m_PartType) + { + case cCompositeChat::ptText: + { + Part["text"] = (*itr)->m_Text; + AddChatPartStyle(Part, (*itr)->m_Style); + break; + } + + case cCompositeChat::ptClientTranslated: + { + const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; + Part["translate"] = p.m_Text; + Json::Value With; + for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) + { + With.append(*itrW); + } + if (!p.m_Parameters.empty()) + { + Part["with"] = With; + } + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptUrl: + { + const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Url; + Url["action"] = "open_url"; + Url["value"] = p.m_Url; + Part["clickEvent"] = Url; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptSuggestCommand: + case cCompositeChat::ptRunCommand: + { + const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Cmd; + Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; + Cmd["value"] = p.m_Command; + Part["clickEvent"] = Cmd; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptShowAchievement: + { + const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; + Part["translate"] = "chat.type.achievement"; + + Json::Value Ach; + Ach["action"] = "show_achievement"; + Ach["value"] = p.m_Text; + + Json::Value AchColourAndName; + AchColourAndName["color"] = "green"; + AchColourAndName["translate"] = p.m_Text; + AchColourAndName["hoverEvent"] = Ach; + + Json::Value Extra; + Extra.append(AchColourAndName); + + Json::Value Name; + Name["text"] = p.m_PlayerName; + + Json::Value With; + With.append(Name); + With.append(Extra); + + Part["with"] = With; + AddChatPartStyle(Part, p.m_Style); + break; + } + } + msg["extra"].append(Part); + } // for itr - Parts[] + + // Send the message to the client: + cPacketizer Pkt(*this, 0x02); + Pkt.WriteString(msg.toStyledString()); + Pkt.WriteChar(0); +} + + + + + +void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x04); // Entity Equipment packet + Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); + Pkt.WriteShort(a_SlotNum); + Pkt.WriteItem(a_Item); +} + + + + + +void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +{ + // Send the Join Game packet: + { + cServer * Server = cRoot::Get()->GetServer(); + cPacketizer Pkt(*this, 0x01); // Join Game packet + Pkt.WriteInt(a_Player.GetUniqueID()); + Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 + Pkt.WriteChar((char)a_World.GetDimension()); + Pkt.WriteByte(2); // TODO: Difficulty (set to Normal) + Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60)); + Pkt.WriteString("default"); // Level type - wtf? + Pkt.WriteBool(false); // Reduced Debug Info - wtf? + } + m_LastSentDimension = a_World.GetDimension(); + + // Send the spawn position: + { + cPacketizer Pkt(*this, 0x05); // Spawn Position packet + Vector3i Position(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); + Pkt.WritePosition(Position); + } + + // Send player abilities: + SendPlayerAbilities(); +} + + + + + +void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +{ + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "1.8"; + Version["protocol"] = 47; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = ServerDescription.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + Json::StyledWriter Writer; + AString Response = Writer.write(ResponseValue); + + cPacketizer Pkt(*this, 0x00); // Response packet + Pkt.WriteString(Response); +} + + + + + +void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) +{ + AString Username; + if (!a_ByteBuffer.ReadVarUTF8String(Username)) + { + m_Client->Kick("Bad username"); + return; + } + + if (!m_Client->HandleHandshake(Username)) + { + // The client is not welcome here, they have been sent a Kick packet already + return; + } + + cServer * Server = cRoot::Get()->GetServer(); + // If auth is required, then send the encryption request: + if (Server->ShouldAuthenticate()) + { + cPacketizer Pkt(*this, 0x01); + Pkt.WriteString(Server->GetServerID()); + const AString & PubKeyDer = Server->GetPublicKeyDER(); + Pkt.WriteVarInt((short)PubKeyDer.size()); + Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size()); + Pkt.WriteVarInt(4); + Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) + m_Client->SetUsername(Username); + return; + } + + m_Client->HandleLogin(4, Username); +} + + + + + +void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) +{ + UInt32 EncKeyLength, EncNonceLength; + a_ByteBuffer.ReadVarInt(EncKeyLength); + AString EncKey; + if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) + { + return; + } + a_ByteBuffer.ReadVarInt(EncNonceLength); + AString EncNonce; + if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) + { + return; + } + if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) + { + LOGD("Too long encryption"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt EncNonce using privkey + cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); + Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; + int res = rsaDecryptor.Decrypt((const Byte *)EncNonce.data(), EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); + if (res != 4) + { + LOGD("Bad nonce length: got %d, exp %d", res, 4); + m_Client->Kick("Hacked client"); + return; + } + if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) + { + LOGD("Bad nonce value"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt the symmetric encryption key using privkey: + Byte DecryptedKey[MAX_ENC_LEN]; + res = rsaDecryptor.Decrypt((const Byte *)EncKey.data(), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); + if (res != 16) + { + LOGD("Bad key length"); + m_Client->Kick("Hacked client"); + return; + } + + StartEncryption(DecryptedKey); + m_Client->HandleLogin(4, m_Client->GetUsername()); +} + + + + diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h new file mode 100644 index 000000000..11a376b17 --- /dev/null +++ b/src/Protocol/Protocol18x.h @@ -0,0 +1,76 @@ + +// Protocol18x.h + +/* +Declares the 1.8.x protocol classes: + - cProtocol180 + - release 1.8 protocol (#47) +(others may be added later in the future for the 1.8 release series) +*/ + + + + + +#pragma once + +#include "Protocol.h" +#include "Protocol17x.h" +#include "../ByteBuffer.h" + +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable:4127) + #pragma warning(disable:4244) + #pragma warning(disable:4231) + #pragma warning(disable:4189) + #pragma warning(disable:4702) +#endif + +#ifdef _MSC_VER + #pragma warning(pop) +#endif + + + + + +// fwd: +namespace Json +{ + class Value; +} + + + + + +class cProtocol180 : + public cProtocol176 +{ + typedef cProtocol176 super; + +public: + + cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + + virtual void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat(const AString & a_Message) override; + virtual void SendChat(const cCompositeChat & a_Message) override; + virtual void SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) override {} + virtual void SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendLogin(const cPlayer & a_Player, const cWorld & a_World) override; + +protected: + + virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; + + // Packet handlers while in the Login state (m_State == 2): + virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override; +} ; + + + + diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 8b395230a..642e96880 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -13,6 +13,7 @@ #include "Protocol15x.h" #include "Protocol16x.h" #include "Protocol17x.h" +#include "Protocol18x.h" #include "../ClientHandle.h" #include "../Root.h" #include "../Server.h" @@ -51,7 +52,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) { case PROTO_VERSION_1_2_5: return "1.2.5"; case PROTO_VERSION_1_3_2: return "1.3.2"; - case PROTO_VERSION_1_4_2: return "1.4.2"; + // case PROTO_VERSION_1_4_2: return "1.4.2"; case PROTO_VERSION_1_4_4: return "1.4.4"; case PROTO_VERSION_1_4_6: return "1.4.6"; case PROTO_VERSION_1_5_0: return "1.5"; @@ -62,6 +63,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) case PROTO_VERSION_1_6_4: return "1.6.4"; case PROTO_VERSION_1_7_2: return "1.7.2"; case PROTO_VERSION_1_7_6: return "1.7.6"; + case PROTO_VERSION_1_8_0: return "1.8"; } ASSERT(!"Unknown protocol version"); return Printf("Unknown protocol (%d)", a_ProtocolVersion); @@ -1016,6 +1018,27 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; } + case PROTO_VERSION_1_8_0: + { + AString ServerAddress; + short ServerPort; + UInt32 NextState; + if (!m_Buffer.ReadVarUTF8String(ServerAddress)) + { + break; + } + if (!m_Buffer.ReadBEShort(ServerPort)) + { + break; + } + if (!m_Buffer.ReadVarInt(NextState)) + { + break; + } + m_Buffer.CommitRead(); + m_Protocol = new cProtocol180(m_Client, ServerAddress, (UInt16)ServerPort, NextState); + return true; + } } LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u)", m_Client->GetIPString().c_str(), ProtocolVersion diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index a05aeda70..2e8976a9f 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -51,6 +51,7 @@ public: // These will be kept "under" the next / latest, because the next and latest are only needed for previous protocols PROTO_VERSION_1_7_2 = 4, PROTO_VERSION_1_7_6 = 5, + PROTO_VERSION_1_8_0 = 47, } ; cProtocolRecognizer(cClientHandle * a_Client); -- cgit v1.2.3 From 472efa8174626a00ffdf5b39e1a44ac419cd3698 Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 3 Sep 2014 16:12:43 -0700 Subject: Globals.h: Added Floor and Ciel casting, C++ cast cleanups, etc Snow Golems must also be above 64Y to spawn snow (as of 1.8). --- src/Entities/Entity.h | 6 +++--- src/Globals.h | 40 ++++++++++++++++++++++++++++++++++++---- src/Mobs/SnowGolem.cpp | 12 +++++++----- src/Vector3.h | 33 ++++++++++++++++----------------- 4 files changed, 62 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b9c280b6b..73e8a0d8b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -27,9 +27,9 @@ return super::GetClass(); \ } -#define POSX_TOINT (int)floor(GetPosX()) -#define POSY_TOINT (int)floor(GetPosY()) -#define POSZ_TOINT (int)floor(GetPosZ()) +#define POSX_TOINT FloorD(GetPosX()) +#define POSY_TOINT FloorD(GetPosY()) +#define POSZ_TOINT FloorD(GetPosZ()) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) #define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } diff --git a/src/Globals.h b/src/Globals.h index de1024010..a782de325 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -217,10 +217,10 @@ template class SizeChecker; // CRT stuff: #include -#include -#include -#include -#include +#include +#include +#include +#include @@ -370,6 +370,38 @@ T Clamp(T a_Value, T a_Min, T a_Max) +/** Floors a_Value, then casts it to C (an int by default) */ +template +C FloorD(double a_Value) +{ + return static_cast(std::floor(a_Value)); +} + +/** Floors a_Value, then casts it to C (an int by default) */ +template +C FloorF(double a_Value) +{ + return static_cast(std::floorf(a_Value)); +} + +/** Ciels a_Value, then casts it to C (an int by default) */ +template +C CeilD(double a_Value) +{ + return static_cast(std::ceil(a_Value)); +} + +/** Ciels a_Value, then casts it to C (an int by default) */ +template +C CeilF(double a_Value) +{ + return static_cast(std::ceilf(a_Value)); +} + + + + + #ifndef TOLUA_TEMPLATE_BIND #define TOLUA_TEMPLATE_BIND(x) #endif diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 76334d970..43ce16ee4 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -30,17 +30,19 @@ void cSnowGolem::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (IsBiomeNoDownfall(m_World->GetBiomeAt((int) floor(GetPosX()), (int) floor(GetPosZ())))) + if (IsBiomeNoDownfall(m_World->GetBiomeAt(POSX_TOINT, POSZ_TOINT))) { TakeDamage(*this); } else { - BLOCKTYPE BlockBelow = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()) - 1, (int) floor(GetPosZ())); - BLOCKTYPE Block = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ())); - if (Block == E_BLOCK_AIR && cBlockInfo::IsSolid(BlockBelow)) + BLOCKTYPE BlockBelow = m_World->GetBlock(POSX_TOINT, POSY_TOINT - 1, POSZ_TOINT); + BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT); + if (Block == E_BLOCK_AIR + && cBlockInfo::IsSolid(BlockBelow) + && GetPosY() >= 64) // Must be at at least 64Y for snow to form { - m_World->SetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ()), E_BLOCK_SNOW, 0); + m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_SNOW, 0); } } } diff --git a/src/Vector3.h b/src/Vector3.h index 1dcb38f64..782b0d1c9 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -4,7 +4,6 @@ #define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) -#include #include #include @@ -29,9 +28,9 @@ public: // Hardcoded copy constructors (tolua++ does not support function templates .. yet) - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} // tolua_end @@ -53,9 +52,9 @@ public: { double Len = 1.0 / Length(); - x = (T)(x * Len); - y = (T)(y * Len); - z = (T)(z * Len); + x = static_cast(x * Len); + y = static_cast(y * Len); + z = static_cast(z * Len); } inline Vector3 NormalizeCopy(void) const @@ -63,9 +62,9 @@ public: double Len = 1.0 / Length(); return Vector3( - (T)(x * Len), - (T)(y * Len), - (T)(z * Len) + static_cast(x * Len), + static_cast(y * Len), + static_cast(z * Len) ); } @@ -74,15 +73,15 @@ public: double Len = 1.0 / Length(); a_Rhs.Set( - (T)(x * Len), - (T)(y * Len), - (T)(z * Len) + static_cast(x * Len), + static_cast(y * Len), + static_cast(z * Len) ); } inline double Length(void) const { - return sqrt((double)(x * x + y * y + z * z)); + return sqrt(static_cast(x * x + y * y + z * z)); } inline double SqrLength(void) const @@ -138,9 +137,9 @@ public: inline Vector3 Floor(void) const { return Vector3( - (int)floor(x), - (int)floor(y), - (int)floor(z) + static_cast(floor(x)), + static_cast(floor(y)), + static_cast(floor(z)) ); } -- cgit v1.2.3 From 19067b27de62574c338eed45ddabdfee2ad89d9c Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 3 Sep 2014 16:18:58 -0700 Subject: In 1.8, carrots and potatoes yield one less hunger point. --- src/Items/ItemFood.h | 2 +- src/Items/ItemSeeds.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 8bea19fba..9035344df 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -29,7 +29,7 @@ public: switch (m_ItemType) { // Please keep alpha-sorted. - case E_ITEM_BAKED_POTATO: return FoodInfo(6, 7.2); + case E_ITEM_BAKED_POTATO: return FoodInfo(5, 7.2); case E_ITEM_BREAD: return FoodInfo(5, 6); // Carrots handled in ItemSeeds case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2); diff --git a/src/Items/ItemSeeds.h b/src/Items/ItemSeeds.h index 54a1183d7..e1db7c5f4 100644 --- a/src/Items/ItemSeeds.h +++ b/src/Items/ItemSeeds.h @@ -37,7 +37,7 @@ public: { switch (m_ItemType) { - case E_ITEM_CARROT: return FoodInfo(4, 4.8); + case E_ITEM_CARROT: return FoodInfo(3, 4.8); case E_ITEM_POTATO: return FoodInfo(1, 0.6); default: return FoodInfo(0, 0); } -- cgit v1.2.3 From e1206568ec71c0e7017c1f764fdc146ba86ce30a Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 3 Sep 2014 16:22:04 -0700 Subject: Revert "Globals.h: Added Floor and Ciel casting, C++ cast cleanups, etc" This reverts commit 472efa8174626a00ffdf5b39e1a44ac419cd3698. Apparently we don't support some of these features quite yet (darn you C++98!) --- src/Entities/Entity.h | 6 +++--- src/Globals.h | 40 ++++------------------------------------ src/Mobs/SnowGolem.cpp | 12 +++++------- src/Vector3.h | 33 +++++++++++++++++---------------- 4 files changed, 29 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 73e8a0d8b..b9c280b6b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -27,9 +27,9 @@ return super::GetClass(); \ } -#define POSX_TOINT FloorD(GetPosX()) -#define POSY_TOINT FloorD(GetPosY()) -#define POSZ_TOINT FloorD(GetPosZ()) +#define POSX_TOINT (int)floor(GetPosX()) +#define POSY_TOINT (int)floor(GetPosY()) +#define POSZ_TOINT (int)floor(GetPosZ()) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) #define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } diff --git a/src/Globals.h b/src/Globals.h index a782de325..de1024010 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -217,10 +217,10 @@ template class SizeChecker; // CRT stuff: #include -#include -#include -#include -#include +#include +#include +#include +#include @@ -370,38 +370,6 @@ T Clamp(T a_Value, T a_Min, T a_Max) -/** Floors a_Value, then casts it to C (an int by default) */ -template -C FloorD(double a_Value) -{ - return static_cast(std::floor(a_Value)); -} - -/** Floors a_Value, then casts it to C (an int by default) */ -template -C FloorF(double a_Value) -{ - return static_cast(std::floorf(a_Value)); -} - -/** Ciels a_Value, then casts it to C (an int by default) */ -template -C CeilD(double a_Value) -{ - return static_cast(std::ceil(a_Value)); -} - -/** Ciels a_Value, then casts it to C (an int by default) */ -template -C CeilF(double a_Value) -{ - return static_cast(std::ceilf(a_Value)); -} - - - - - #ifndef TOLUA_TEMPLATE_BIND #define TOLUA_TEMPLATE_BIND(x) #endif diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 43ce16ee4..76334d970 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -30,19 +30,17 @@ void cSnowGolem::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (IsBiomeNoDownfall(m_World->GetBiomeAt(POSX_TOINT, POSZ_TOINT))) + if (IsBiomeNoDownfall(m_World->GetBiomeAt((int) floor(GetPosX()), (int) floor(GetPosZ())))) { TakeDamage(*this); } else { - BLOCKTYPE BlockBelow = m_World->GetBlock(POSX_TOINT, POSY_TOINT - 1, POSZ_TOINT); - BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT); - if (Block == E_BLOCK_AIR - && cBlockInfo::IsSolid(BlockBelow) - && GetPosY() >= 64) // Must be at at least 64Y for snow to form + BLOCKTYPE BlockBelow = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()) - 1, (int) floor(GetPosZ())); + BLOCKTYPE Block = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ())); + if (Block == E_BLOCK_AIR && cBlockInfo::IsSolid(BlockBelow)) { - m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_SNOW, 0); + m_World->SetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ()), E_BLOCK_SNOW, 0); } } } diff --git a/src/Vector3.h b/src/Vector3.h index 782b0d1c9..1dcb38f64 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -4,6 +4,7 @@ #define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) +#include #include #include @@ -28,9 +29,9 @@ public: // Hardcoded copy constructors (tolua++ does not support function templates .. yet) - Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} - Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} - Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} // tolua_end @@ -52,9 +53,9 @@ public: { double Len = 1.0 / Length(); - x = static_cast(x * Len); - y = static_cast(y * Len); - z = static_cast(z * Len); + x = (T)(x * Len); + y = (T)(y * Len); + z = (T)(z * Len); } inline Vector3 NormalizeCopy(void) const @@ -62,9 +63,9 @@ public: double Len = 1.0 / Length(); return Vector3( - static_cast(x * Len), - static_cast(y * Len), - static_cast(z * Len) + (T)(x * Len), + (T)(y * Len), + (T)(z * Len) ); } @@ -73,15 +74,15 @@ public: double Len = 1.0 / Length(); a_Rhs.Set( - static_cast(x * Len), - static_cast(y * Len), - static_cast(z * Len) + (T)(x * Len), + (T)(y * Len), + (T)(z * Len) ); } inline double Length(void) const { - return sqrt(static_cast(x * x + y * y + z * z)); + return sqrt((double)(x * x + y * y + z * z)); } inline double SqrLength(void) const @@ -137,9 +138,9 @@ public: inline Vector3 Floor(void) const { return Vector3( - static_cast(floor(x)), - static_cast(floor(y)), - static_cast(floor(z)) + (int)floor(x), + (int)floor(y), + (int)floor(z) ); } -- cgit v1.2.3 From 07fba5c98ec94f98b742e8aa76dcec5572bfcecb Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 4 Sep 2014 03:22:35 +0200 Subject: Added more 1.8 protocol things. --- src/Protocol/ChunkDataSerializer.cpp | 64 +++++ src/Protocol/ChunkDataSerializer.h | 4 +- src/Protocol/Protocol17x.cpp | 1 + src/Protocol/Protocol17x.h | 18 +- src/Protocol/Protocol18x.cpp | 523 ++++++++++++++++++++++++++++++++++- src/Protocol/Protocol18x.h | 36 +++ 6 files changed, 632 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index ebe61631b..9eadc4f0b 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -43,6 +43,7 @@ const AString & cChunkDataSerializer::Serialize(int a_Version) { case RELEASE_1_2_5: Serialize29(data); break; case RELEASE_1_3_2: Serialize39(data); break; + case RELEASE_1_8_0: Serialize80(data); break; // TODO: Other protocol versions may serialize the data differently; implement here default: @@ -174,3 +175,66 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) + +void cChunkDataSerializer::Serialize80(AString & a_Data) +{ + // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) + + // Blocktypes converter (1.8 included the meta into the blocktype): + unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)]; + for (int RelX = 0; RelX < cChunkDef::Width; RelX++) + { + for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++) + { + for (int RelY = 0; RelY < cChunkDef::Height; RelY++) + { + int Index = cChunkDef::MakeIndexNoCheck(RelX, RelY, RelZ); + BLOCKTYPE BlockType = m_BlockTypes[Index]; + NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; + + Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta & 15); + } + } + } + + const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; + const int BlockLightOffset = sizeof(Blocks); + const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight); + const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight); + const int DataSize = BiomeOffset + BiomeDataSize; + + // Temporary buffer for the composed data: + char AllData [DataSize]; + memcpy(AllData, Blocks, sizeof(Blocks)); + memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight)); + memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight)); + memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize); + + // Put all those data into a_Data: + a_Data.push_back('\x01'); // "Ground-up continuous", or rather, "biome data present" flag + + // Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively + // Also, no endian flipping is needed because of the const values + unsigned short BitMap = 0xffff; + a_Data.append((const char *)&BitMap, sizeof(short)); + + // Write chunk size: + UInt32 ChunkSize = htonl((UInt32)DataSize); + + unsigned char b[5]; // // A 32-bit integer can be encoded by at most 5 bytes + size_t idx = 0; + UInt32 Value = ChunkSize; + do + { + b[idx] = (Value & 0x7f) | ((Value > 0x7f) ? 0x80 : 0x00); + Value = Value >> 7; + idx++; + } while (Value > 0); + a_Data.append((const char *)b, idx); + + a_Data.append(AllData, ChunkSize); // Chunk data +} + + + + diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index a42856356..4c33aede1 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -23,13 +23,15 @@ protected: Serializations m_Serializations; void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5 - void Serialize39(AString & a_Data); // Release 1.3.1 and 1.3.2 + void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10 + void Serialize80(AString & a_Data); // Release 1.8 public: enum { RELEASE_1_2_5 = 29, RELEASE_1_3_2 = 39, + RELEASE_1_8_0 = 47, } ; cChunkDataSerializer( diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 00b115c8f..88b4693c9 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2614,6 +2614,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) + void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEntity) { cFastNBTWriter Writer; diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index ec948e8a1..be94c0d61 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -146,6 +146,7 @@ protected: m_Lock(a_Protocol.m_CSPacket) { m_Out.WriteVarInt(a_PacketType); + LOG("Send packet %i", a_PacketType); } ~cPacketizer(); @@ -211,6 +212,7 @@ protected: } void WriteItem(const cItem & a_Item); + void WriteItem180(const cItem & a_Item); void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f @@ -277,21 +279,21 @@ protected: void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); - void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); - void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); - void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); void HandlePacketPlayer (cByteBuffer & a_ByteBuffer); void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer); void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer); - void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); - void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); - void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer); - void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer); - void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 0a455c70e..4dbb2207c 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -11,6 +11,7 @@ Implements the 1.8.x protocol classes: #include "Globals.h" #include "Bindings/PluginManager.h" #include "json/json.h" +#include "ChunkDataSerializer.h" #include "Protocol18x.h" #include "../ClientHandle.h" @@ -20,14 +21,25 @@ Implements the 1.8.x protocol classes: #include "../World.h" #include "../Entities/Player.h" +#include "Entities/Painting.h" -class cProtocol176; + + + + +#define HANDLE_READ(ByteBuf, Proc, Type, Var) \ + Type Var; \ + if (!ByteBuf.Proc(Var))\ + {\ + return;\ + } const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... +class cProtocol176; @@ -45,6 +57,347 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd +void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x2A); + Pkt.WriteString(a_ParticleName); + Pkt.WriteFloat(a_SrcX); + Pkt.WriteFloat(a_SrcY); + Pkt.WriteFloat(a_SrcZ); + Pkt.WriteFloat(a_OffsetX); + Pkt.WriteFloat(a_OffsetY); + Pkt.WriteFloat(a_OffsetZ); + Pkt.WriteFloat(a_ParticleData); + Pkt.WriteInt(a_ParticleAmmount);*/ +} + + + + + +void cProtocol180::SendPlayerMoveLook(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteDouble(Player->GetPosX()); + + // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. + Pkt.WriteDouble(Player->GetStance() + 0.001); + + Pkt.WriteDouble(Player->GetPosZ()); + Pkt.WriteFloat((float)Player->GetYaw()); + Pkt.WriteFloat((float)Player->GetPitch()); + Pkt.WriteByte(0); +} + + + + + +void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0a); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); +} + + + + + +void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0d); // Collect Item packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteVarInt(a_Player.GetUniqueID()); +} + + + + + +void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick + Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); +} + + + + + +void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x13); // Destroy Entities packet + Pkt.WriteVarInt(1); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); +} + + + + + +void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_RelX); + Pkt.WriteByte(a_RelY); + Pkt.WriteByte(a_RelZ); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities +} + + + + + +void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_RelX); + Pkt.WriteByte(a_RelY); + Pkt.WriteByte(a_RelZ); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities +} + + + + + +void cProtocol180::SendEntityLook(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x16); // Entity Look packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities +} + + + + + +void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x18); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGrond() on entities +} + + + + + +void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); +} + + + + + +void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteEntityMetadata(a_Entity); + Pkt.WriteByte(0x7f); // The termination byte +} + + + + + +void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_EffectID); + Pkt.WriteByte(a_Amplifier); + Pkt.WriteVarInt((UInt32)a_Duration); + Pkt.WriteBool(false); // Hide particles +} + + + + + +void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1e); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_EffectID); +} + + + + + +void cProtocol180::SendEntityProperties(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x20); // Entity Properties packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteEntityProperties(a_Entity); +} + + + + + +void cProtocol180::SendKeepAlive(int a_PingID) +{ + // Drop the packet if the protocol is not in the Game state yet (caused a client crash): + if (m_State != 3) + { + LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); + return; + } + + cPacketizer Pkt(*this, 0x00); // Keep Alive packet + Pkt.WriteVarInt(a_PingID); +} + + + + + +void cProtocol180::SendHealth(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x06); // Update Health packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteFloat((float)Player->GetHealth()); + Pkt.WriteVarInt((UInt32)Player->GetFoodLevel()); + Pkt.WriteFloat((float)Player->GetFoodSaturationLevel()); +} + + + + + +void cProtocol180::SendExperience(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1f); // Experience Packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteFloat(Player->GetXpPercentage()); + Pkt.WriteVarInt((UInt32)Player->GetXpLevel()); + Pkt.WriteVarInt((UInt32)Player->GetCurrentXp()); +} + + + + + +void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x10); // Spawn Painting packet + Pkt.WriteVarInt(a_Painting.GetUniqueID()); + Pkt.WriteString(a_Painting.GetName().c_str()); + Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ())); + Pkt.WriteChar(a_Painting.GetDirection()); +} + + + + + +void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & a_Message) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x3f); + Pkt.WriteString(a_Channel); + Pkt.WriteBuf(a_Message.data(), a_Message.size());*/ +} + + + + + +void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x21); // Chunk Data packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteBool(true); + Pkt.WriteShort(0); // Primary bitmap + Pkt.WriteVarInt(0); // Data size +} + + + + + +void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) +{ + ASSERT(m_State == 3); // In game mode? + + /*// Serialize first, before creating the Packetizer (the packetizer locks a CS) + // This contains the flags and bitmasks, too + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0); + + cPacketizer Pkt(*this, 0x21); // Chunk Data packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteBuf(ChunkData.data(), ChunkData.size());*/ +} + + + + + void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { ASSERT(m_State == 3); // In game mode? @@ -64,7 +417,7 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x22); // Multi Block Change packet + /*cPacketizer Pkt(*this, 0x22); // Multi Block Change packet Pkt.WriteInt(a_ChunkX); Pkt.WriteInt(a_ChunkZ); Pkt.WriteVarInt((UInt32)a_Changes.size()); @@ -75,7 +428,7 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15); Pkt.WriteVarInt(Block); - } // for itr - a_Changes[] + } // for itr - a_Changes[]*/ } @@ -204,10 +557,10 @@ void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x04); // Entity Equipment packet + /*cPacketizer Pkt(*this, 0x04); // Entity Equipment packet Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); Pkt.WriteShort(a_SlotNum); - Pkt.WriteItem(a_Item); + Pkt.WriteItem(a_Item);*/ } @@ -245,6 +598,50 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID); + switch (ActionID) + { + case 0: + { + // Respawn + m_Client->HandleRespawn(); + break; + } + case 1: + { + // Request stats + const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); + SendStatistics(Manager); + + break; + } + case 2: + { + // Open Inventory achievement + m_Client->GetPlayer()->AwardAchievement(achOpenInv); + break; + } + } +} + + + + + +void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + AString Data; + a_ByteBuffer.ReadAll(Data); + m_Client->HandlePluginMessage(Channel, Data); +} + + + + + void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) { cServer * Server = cRoot::Get()->GetServer(); @@ -383,3 +780,119 @@ void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe + +void cProtocol180::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); + HANDLE_READ(a_ByteBuffer, ReadChar, char, Flags); + + if ((Flags & 0x2) != 0) + { + m_Client->HandleUnmount(); + } + else if ((Flags & 0x1) != 0) + { + m_Client->HandleSteerVehicle(Forward, Sideways); + } +} + + + + + +void cProtocol180::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID); + HANDLE_READ(a_ByteBuffer, ReadChar, char, Action); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost); + + switch (Action) + { + case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch + case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch + case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed + case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting + case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting + } +} + + + + + +void cProtocol180::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type); + + switch (Type) + { + case 0: + { + m_Client->HandleUseEntity((int)EntityID, false); + break; + } + case 1: + { + m_Client->HandleUseEntity((int)EntityID, true); + break; + } + case 2: + { + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ); + + // TODO: Do anything + break; + } + default: + { + ASSERT(!"Unhandled use entity type!"); + return; + } + } +} + + + + + +void cProtocol180::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID); + m_Client->HandleKeepAlive((int)KeepAliveID); +} + + + + + +void cProtocol180::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + 1.62, IsOnGround); +} + + + + + +void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround); +} + + + + diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 11a376b17..6604cbc3e 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -54,6 +54,32 @@ public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + virtual void SendPickupSpawn (const cPickup & a_Pickup) override {} + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {} + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override {} + virtual void SendWholeInventory (const cWindow & a_Window) override {} + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityLook(const cEntity & a_Entity) override; + virtual void SendTeleportEntity(const cEntity & a_Entity) override; + virtual void SendEntityHeadLook(const cEntity & a_Entity) override; + virtual void SendEntityMetadata(const cEntity & a_Entity) override; + virtual void SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) override; + virtual void SendEntityProperties(const cEntity & a_Entity) override; + virtual void SendKeepAlive(int a_PingID) override; + virtual void SendHealth(void) override; + virtual void SendExperience(void) override; + virtual void SendPaintingSpawn(const cPainting & a_Painting) override; + virtual void SendPluginMessage(const AString & a_Channel, const AString & a_Message) override; + virtual void SendUnloadChunk(int a_ChunkX, int a_ChunkZ) override; + virtual void SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; virtual void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; virtual void SendChat(const AString & a_Message) override; @@ -69,6 +95,16 @@ protected: // Packet handlers while in the Login state (m_State == 2): virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override; + + // Packet handlers while in the Game state (m_State == 3): + virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override; } ; -- cgit v1.2.3 From d77221c7157a7a371cdbc7b00abe287199be3c86 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 4 Sep 2014 14:00:54 +0200 Subject: Anvil: Cleanly refuse to store data that is too large. Each chunk in MCA needs to be less than 1 MiB compressed; chunks that are larger will be refused with a log message. --- src/WorldStorage/WSSAnvil.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 239f4a155..4d2f92173 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2905,7 +2905,13 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri // Store the header: ChunkSize = ((u_long)a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number - ASSERT(ChunkSize < 256); + if (ChunkSize > 255) + { + LOGWARNING("Cannot save chunk [%d, %d], the data is too large (%u KiB, maximum is 1024 KiB). Remove some entities and retry.", + a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, (unsigned)(ChunkSize * 4) + ); + return false; + } m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); if (m_File.Seek(0) < 0) { -- cgit v1.2.3 From 7ab4c078b873433a9b353b742a9a39540dd5219b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 4 Sep 2014 14:05:42 +0200 Subject: Fixed compilation after chunk Y removal. --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 557434fbb..8c765c8c9 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1789,7 +1789,7 @@ bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & { for (int x = MinChunkX; x <= MaxChunkX; x++) { - cChunkPtr Chunk = GetChunkNoGen(x, ZERO_CHUNK_Y, z); + cChunkPtr Chunk = GetChunkNoGen(x, z); if ((Chunk == NULL) || !Chunk->IsValid()) { continue; -- cgit v1.2.3 From da28c70def4be849925709b2c4d4857b6db1abb8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 4 Sep 2014 19:03:21 +0200 Subject: Fixed client errors. --- src/Protocol/ChunkDataSerializer.cpp | 32 +++---------- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol17x.h | 3 +- src/Protocol/Protocol18x.cpp | 90 ++++++++++++++++++++++++++---------- src/Protocol/Protocol18x.h | 4 ++ 5 files changed, 79 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 9eadc4f0b..29e32ce32 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -182,19 +182,11 @@ void cChunkDataSerializer::Serialize80(AString & a_Data) // Blocktypes converter (1.8 included the meta into the blocktype): unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)]; - for (int RelX = 0; RelX < cChunkDef::Width; RelX++) + for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++) { - for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++) - { - for (int RelY = 0; RelY < cChunkDef::Height; RelY++) - { - int Index = cChunkDef::MakeIndexNoCheck(RelX, RelY, RelZ); - BLOCKTYPE BlockType = m_BlockTypes[Index]; - NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; - - Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta & 15); - } - } + BLOCKTYPE BlockType = m_BlockTypes[Index]; + NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; + Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta); } const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; @@ -216,23 +208,13 @@ void cChunkDataSerializer::Serialize80(AString & a_Data) // Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively // Also, no endian flipping is needed because of the const values unsigned short BitMap = 0xffff; - a_Data.append((const char *)&BitMap, sizeof(short)); + a_Data.append((const char *)&BitMap, sizeof(unsigned short)); // Write chunk size: UInt32 ChunkSize = htonl((UInt32)DataSize); + a_Data.append((const char *)&ChunkSize, 4); - unsigned char b[5]; // // A 32-bit integer can be encoded by at most 5 bytes - size_t idx = 0; - UInt32 Value = ChunkSize; - do - { - b[idx] = (Value & 0x7f) | ((Value > 0x7f) ? 0x80 : 0x00); - Value = Value >> 7; - idx++; - } while (Value > 0); - a_Data.append((const char *)b, idx); - - a_Data.append(AllData, ChunkSize); // Chunk data + a_Data.append(AllData, DataSize); // Chunk data } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 88b4693c9..b4f30b639 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1924,7 +1924,7 @@ void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape); m_Client->SetLocale(Locale); - // TODO: handle in m_Client + // TODO: Do anything with the other values. } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index be94c0d61..d715e1cec 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -146,7 +146,6 @@ protected: m_Lock(a_Protocol.m_CSPacket) { m_Out.WriteVarInt(a_PacketType); - LOG("Send packet %i", a_PacketType); } ~cPacketizer(); @@ -278,7 +277,7 @@ protected: void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); - void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 4dbb2207c..a3e72d4dd 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -57,6 +57,29 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd +void cProtocol180::SendLoginSuccess(void) +{ + ASSERT(m_State == 2); // State: login? + + // Disable compression: + { + cPacketizer Pkt(*this, 0x03); // Set compression packet + Pkt.WriteVarInt(-1); + } + + { + cPacketizer Pkt(*this, 0x02); // Login success packet + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); + Pkt.WriteString(m_Client->GetUsername()); + } + + m_State = 3; // State = Game +} + + + + + void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) { ASSERT(m_State == 3); // In game mode? @@ -81,7 +104,7 @@ void cProtocol180::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x08); // Player Position And Look packet + /*cPacketizer Pkt(*this, 0x08); // Player Position And Look packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteDouble(Player->GetPosX()); @@ -91,7 +114,7 @@ void cProtocol180::SendPlayerMoveLook(void) Pkt.WriteDouble(Player->GetPosZ()); Pkt.WriteFloat((float)Player->GetYaw()); Pkt.WriteFloat((float)Player->GetPitch()); - Pkt.WriteByte(0); + Pkt.WriteByte(0);*/ } @@ -128,12 +151,12 @@ void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x12); // Entity Velocity packet + /*cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); - Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400));*/ } @@ -144,9 +167,9 @@ void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x13); // Destroy Entities packet + /*cPacketizer Pkt(*this, 0x13); // Destroy Entities packet Pkt.WriteVarInt(1); - Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteVarInt(a_Entity.GetUniqueID());*/ } @@ -157,12 +180,12 @@ void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet + /*cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_RelX); Pkt.WriteByte(a_RelY); Pkt.WriteByte(a_RelZ); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } @@ -173,14 +196,14 @@ void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + /*cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_RelX); Pkt.WriteByte(a_RelY); Pkt.WriteByte(a_RelZ); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } @@ -191,11 +214,11 @@ void cProtocol180::SendEntityLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x16); // Entity Look packet + /*cPacketizer Pkt(*this, 0x16); // Entity Look packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } @@ -206,14 +229,14 @@ void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x18); + /*cPacketizer Pkt(*this, 0x18); Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteFPInt(a_Entity.GetPosX()); Pkt.WriteFPInt(a_Entity.GetPosY()); Pkt.WriteFPInt(a_Entity.GetPosZ()); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGrond() on entities + Pkt.WriteBool(true); // TODO: IsOnGrond() on entities*/ } @@ -224,9 +247,9 @@ void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + /*cPacketizer Pkt(*this, 0x19); // Entity Head Look packet Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); + Pkt.WriteByteAngle(a_Entity.GetHeadYaw());*/ } @@ -237,10 +260,10 @@ void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + /*cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteEntityMetadata(a_Entity); - Pkt.WriteByte(0x7f); // The termination byte + Pkt.WriteByte(0x7f); // The termination byte*/ } @@ -340,11 +363,11 @@ void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x10); // Spawn Painting packet + /*cPacketizer Pkt(*this, 0x10); // Spawn Painting packet Pkt.WriteVarInt(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName().c_str()); Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ())); - Pkt.WriteChar(a_Painting.GetDirection()); + Pkt.WriteChar(a_Painting.GetDirection());*/ } @@ -384,14 +407,14 @@ void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize { ASSERT(m_State == 3); // In game mode? - /*// Serialize first, before creating the Packetizer (the packetizer locks a CS) + // Serialize first, before creating the Packetizer (the packetizer locks a CS) // This contains the flags and bitmasks, too const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0); cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteInt(a_ChunkX); Pkt.WriteInt(a_ChunkZ); - Pkt.WriteBuf(ChunkData.data(), ChunkData.size());*/ + Pkt.WriteBuf(ChunkData.data(), ChunkData.size()); } @@ -451,7 +474,7 @@ void cProtocol180::SendChat(const AString & a_Message) void cProtocol180::SendChat(const cCompositeChat & a_Message) { ASSERT(m_State == 3); // In game mode? - + // Compose the complete Json string to send: Json::Value msg; cWorld * World = m_Client->GetPlayer()->GetWorld(); @@ -634,7 +657,10 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - a_ByteBuffer.ReadAll(Data); + if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) + { + return; + } m_Client->HandlePluginMessage(Channel, Data); } @@ -896,3 +922,19 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) + +void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors); + HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags); + + m_Client->SetLocale(Locale); + // TODO: Handle other values +} + + + + diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 6604cbc3e..5c6111958 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -54,6 +54,9 @@ public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + virtual void SendLoginSuccess (void) override; + virtual void SendPlayerAbilities (void) override {} + virtual void SendWindowClose (const cWindow & a_Window) override {} virtual void SendPickupSpawn (const cPickup & a_Pickup) override {} virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {} virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override {} @@ -105,6 +108,7 @@ protected: virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override; } ; -- cgit v1.2.3 From 254c8c9154e8355f139e43cf482366bb4855a4f8 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 16:40:03 +0300 Subject: Anvil: Fixed loading block entities with invalid Y coord. --- src/WorldStorage/WSSAnvil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 4d2f92173..b8f8ba019 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -589,7 +589,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con // Get the BlockEntity's position int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, Child, x, y, z)) + if (!GetBlockEntityNBTPos(a_NBT, Child, x, y, z) || (y < 0) || (y >= cChunkDef::Height)) { LOGWARNING("Bad block entity, missing the coords. Will be ignored."); continue; -- cgit v1.2.3 From 6444bc25ba326b20f2d6bd2e64992e7d7b8e7231 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 16:55:16 +0200 Subject: Fixed security: Player cannot spawn in a disabled world. --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 756410989..51a1f8699 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1670,7 +1670,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents); m_LoadedWorldName = root.get("world", "world").asString(); - a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), true); + a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), false); m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); -- cgit v1.2.3 From 60e235362c9662ad01b68141b32f5aae28a2fdfe Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 22:07:13 +0200 Subject: Fixed style. --- src/Generating/BioGen.cpp | 4 ++-- src/Generating/BioGen.h | 14 +++++++++----- src/Generating/ComposableGenerator.cpp | 4 ++-- 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 175e4ef33..60ad4e3eb 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -227,7 +227,7 @@ cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_Cache cBioGenMulticache::~cBioGenMulticache() { - for (std::vector::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) + for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) { delete *it; } @@ -251,7 +251,7 @@ void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMa void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) { - for (std::vector::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) + for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) { cBiomeGen * tmp = *it; tmp->InitializeBiomeGen(a_IniFile); diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index a4cf95a72..20d199611 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -87,16 +87,20 @@ class cBioGenMulticache : typedef cBiomeGen super; public: - /* - a_CacheSize defines the size of each singular cache - a_CachesLength defines how many caches are used for the multicache + /* + a_CacheSize defines the size of each singular cache + a_CachesLength defines how many caches are used for the multicache */ cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache ~cBioGenMulticache(); protected: - size_t m_CachesLength; - std::vector m_Caches; + typedef std::vector cBiomeGens; + + + size_t m_CachesLength; + cBiomeGens m_Caches; + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index d70438bf3..d98153e22 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -243,12 +243,12 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) } LOGD("Using a cache for biomegen of size %d.", CacheSize); m_UnderlyingBiomeGen = m_BiomeGen; - if (MultiCacheLength > 0) + if (MultiCacheLength > 0) { LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); } - else + else { m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); } -- cgit v1.2.3 From e15b8600a6dcc16fcfb406ee18eb6568d0de7994 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 22:08:00 +0200 Subject: BiomeMultiCache is not used for simple generators. --- src/Generating/ComposableGenerator.cpp | 43 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index d98153e22..69068d231 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -230,29 +230,30 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) // Add a cache, if requested: int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); - int MultiCacheLength = a_IniFile.GetValueSetI("Generator", "BiomeGenMultiCacheLength", 4); - if (CacheSize > 0) + if (CacheSize <= 0) { - if (CacheSize < 4) - { - LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", - CacheSize, 4 - ); - CacheSize = 4; - } - LOGD("Using a cache for biomegen of size %d.", CacheSize); - m_UnderlyingBiomeGen = m_BiomeGen; - if (MultiCacheLength > 0) - { - LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); - m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); - } - else - { - m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); - } - + return; + } + + int MultiCacheLength = a_IniFile.GetValueSetI("Generator", "BiomeGenMultiCacheLength", 4); + if (CacheSize < 4) + { + LOGWARNING("Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", + CacheSize, 4 + ); + CacheSize = 4; + } + LOGD("Using a cache for biomegen of size %d.", CacheSize); + m_UnderlyingBiomeGen = m_BiomeGen; + if (MultiCacheLength > 0) + { + LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); + m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); + } + else + { + m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); } } -- cgit v1.2.3 From 137b021d26d47b11fc27df1c0b52f408f0ef5257 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 22:16:48 +0200 Subject: Rewritten chunk status to specify whether the chunk is in queue. This fixes #1370. --- src/Chunk.cpp | 50 +++++++++++++++++++------- src/Chunk.h | 44 +++++++++++++++++++---- src/ChunkMap.cpp | 75 +++++++++++++-------------------------- src/ChunkMap.h | 9 ++--- src/Generating/ChunkGenerator.cpp | 3 +- src/Generating/ChunkGenerator.h | 4 +++ src/World.cpp | 38 ++++++++++---------- src/World.h | 14 ++++---- src/WorldStorage/WorldStorage.cpp | 11 +++--- 9 files changed, 141 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 9fb178bc3..caace5024 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -71,7 +71,7 @@ cChunk::cChunk( cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, cAllocationPool & a_Pool ) : - m_IsValid(false), + m_Presence(cpInvalid), m_IsLightValid(false), m_IsDirty(false), m_IsSaving(false), @@ -165,11 +165,22 @@ cChunk::~cChunk() -void cChunk::SetValid(void) +void cChunk::SetPresence(cChunk::ePresence a_Presence) { - m_IsValid = true; - - m_World->GetChunkMap()->ChunkValidated(); + m_Presence = a_Presence; + if (a_Presence == cpPresent) + { + m_World->GetChunkMap()->ChunkValidated(); + } +} + + + + + +void cChunk::SetShouldGenerateIfLoadFailed(bool a_ShouldGenerateIfLoadFailed) +{ + m_ShouldGenerateIfLoadFailed = a_ShouldGenerateIfLoadFailed; } @@ -178,6 +189,9 @@ void cChunk::SetValid(void) void cChunk::MarkRegenerating(void) { + // Set as queued again: + SetPresence(cpQueued); + // Tell all clients attached to this chunk that they want this chunk: for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) { @@ -191,7 +205,11 @@ void cChunk::MarkRegenerating(void) bool cChunk::CanUnload(void) { - return m_LoadedByClient.empty() && !m_IsDirty && (m_StayCount == 0); + return + m_LoadedByClient.empty() && // The chunk is not used by any client + !m_IsDirty && // The chunk has been saved properly or hasn't been touched since the load / gen + (m_StayCount == 0) && // The chunk is not in a ChunkStay + (m_Presence != cpQueued) ; // The chunk is not queued for loading / generating (otherwise multi-load / multi-gen could occur) } @@ -223,7 +241,7 @@ void cChunk::MarkSaved(void) void cChunk::MarkLoaded(void) { m_IsDirty = false; - SetValid(); + SetPresence(cpPresent); } @@ -232,12 +250,17 @@ void cChunk::MarkLoaded(void) void cChunk::MarkLoadFailed(void) { - if (m_IsValid) + ASSERT(m_Presence == cpQueued); + + // If the chunk is marked as needed, generate it: + if (m_ShouldGenerateIfLoadFailed) { - return; + m_World->GetGenerator().QueueGenerateChunk(m_PosX, m_PosZ, false); + } + else + { + m_Presence = cpInvalid; } - - m_HasLoadFailed = true; } @@ -246,6 +269,8 @@ void cChunk::MarkLoadFailed(void) void cChunk::GetAllData(cChunkDataCallback & a_Callback) { + ASSERT(m_Presence == cpPresent); + a_Callback.HeightMap(&m_HeightMap); a_Callback.BiomeData(&m_BiomeMap); @@ -272,6 +297,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) { ASSERT(a_SetChunkData.IsHeightMapValid()); ASSERT(a_SetChunkData.AreBiomesValid()); + ASSERT(IsQueued()); memcpy(m_BiomeMap, a_SetChunkData.GetBiomes(), sizeof(m_BiomeMap)); memcpy(m_HeightMap, a_SetChunkData.GetHeightMap(), sizeof(m_HeightMap)); @@ -317,7 +343,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) CreateBlockEntities(); // Set the chunk data as valid. This may be needed for some simulators that perform actions upon block adding (Vaporize) - SetValid(); + SetPresence(cpPresent); // Wake up all simulators for their respective blocks: WakeUpSimulators(); diff --git a/src/Chunk.h b/src/Chunk.h index 0f4928b90..81862f2e7 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -66,6 +66,14 @@ class cChunk : public cChunkDef // The inheritance is "misused" here only to inherit the functions and constants defined in cChunkDef { public: + /** Represents the presence state of the chunk */ + enum ePresence + { + cpInvalid, /**< The chunk is not present at all and is not queued in the loader / generator */ + cpQueued, /**< The chunk is not present, but is queued for loading / generation */ + cpPresent, /**< The chunk is present */ + }; + cChunk( int a_ChunkX, int a_ChunkZ, // Chunk coords cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects @@ -75,11 +83,25 @@ public: cChunk(cChunk & other); ~cChunk(); - bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) - void SetValid(void); // Also wakes up any calls to cChunkMap::GetHeight() - void MarkRegenerating(void); // Marks all clients attached to this chunk as wanting this chunk - bool IsDirty(void) const {return m_IsDirty; } // Returns true if the chunk has changed since it was last saved - bool HasLoadFailed(void) const {return m_HasLoadFailed; } // Returns true if the chunk failed to load and hasn't been generated since then + /** Returns true iff the chunk block data is valid (loaded / generated) */ + bool IsValid(void) const {return (m_Presence == cpPresent); } + + /** Returns true iff the chunk is in the queue for loading / generating */ + bool IsQueued(void) const {return (m_Presence == cpQueued); } + + /** Sets the chunk's presence. + Wakes up any calls to cChunkMap::GetHeight() when setting to cpPresent. */ + void SetPresence(ePresence a_Presence); + + /** Called to indicate whether the chunk should be queued in the generator if it fails to load. Set by cChunkMap::GetChunk(). */ + void SetShouldGenerateIfLoadFailed(bool a_ShouldGenerateIfLoadFailed); + + /** Marks all clients attached to this chunk as wanting this chunk. Also sets presence to cpQueued. */ + void MarkRegenerating(void); + + /** Returns true iff the chunk has changed since it was last saved. */ + bool IsDirty(void) const {return m_IsDirty; } + bool CanUnload(void); bool IsLightValid(void) const {return m_IsLightValid; } @@ -94,7 +116,10 @@ public: void MarkSaving(void); // Marks the chunk as being saved. void MarkSaved(void); // Marks the chunk as saved, if it didn't change from the last call to MarkSaving() void MarkLoaded(void); // Marks the chunk as freshly loaded. Fails if the chunk is already valid - void MarkLoadFailed(void); // Marks the chunk as failed to load. Ignored is the chunk is already valid + + /** Marks the chunk as failed to load. + If m_ShouldGenerateIfLoadFailed is set, queues the chunk for generating. */ + void MarkLoadFailed(void); /** Gets all chunk data, calls the a_Callback's methods for each data type */ void GetAllData(cChunkDataCallback & a_Callback); @@ -434,7 +459,12 @@ private: typedef std::vector sSetBlockQueueVector; - bool m_IsValid; // True if the chunk is loaded / generated + /** Holds the presence status of the chunk - if it is present, or in the loader / generator queue, or unloaded */ + ePresence m_Presence; + + /** If the chunk fails to load, should it be queued in the generator or reset back to invalid? */ + bool m_ShouldGenerateIfLoadFailed; + bool m_IsLightValid; // True if the blocklight and skylight are calculated bool m_IsDirty; // True if the chunk has changed since it was last saved bool m_IsSaving; // True if the chunk is being saved diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 8c765c8c9..50066e539 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -145,10 +145,9 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk(int a_ChunkX, int a_ChunkZ) cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) { - // No need to lock m_CSLayers, since it's already locked by the operation that called us - ASSERT(m_CSLayers.IsLockedByCurrentThread()); + ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us - cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); + cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ); if (Layer == NULL) { // An error must have occurred, since layers are automatically created if they don't exist @@ -160,8 +159,10 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) { return NULL; } - if (!(Chunk->IsValid())) + if (!Chunk->IsValid() && !Chunk->IsQueued()) { + Chunk->SetPresence(cChunk::cpQueued); + Chunk->SetShouldGenerateIfLoadFailed(true); m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, true); } return Chunk; @@ -171,10 +172,11 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ) +cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) { - // No need to lock m_CSLayers, since it's already locked by the operation that called us - cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); + ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us + + cChunkLayer * Layer = GetLayerForChunk(a_ChunkX, a_ChunkZ); if (Layer == NULL) { // An error must have occurred, since layers are automatically created if they don't exist @@ -186,8 +188,9 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ) { return NULL; } - if (!(Chunk->IsValid())) + if (!Chunk->IsValid() && !Chunk->IsQueued()) { + Chunk->SetPresence(cChunk::cpQueued); m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, false); } @@ -200,7 +203,8 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkZ) cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkZ) { - // No need to lock m_CSLayers, since it's already locked by the operation that called us + ASSERT(m_CSLayers.IsLockedByCurrentThread()); // m_CSLayers should already be locked by the operation that called us + cChunkLayer * Layer = GetLayerForChunk( a_ChunkX, a_ChunkZ); if (Layer == NULL) { @@ -1009,6 +1013,17 @@ bool cChunkMap::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blo +bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, a_ChunkZ); + return (Chunk != NULL) && Chunk->IsQueued(); +} + + + + + bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); @@ -2332,48 +2347,6 @@ void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkZ) -/// Loads the chunk synchronously, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) -bool cChunkMap::LoadChunk(int a_ChunkX, int a_ChunkZ) -{ - { - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkZ); - if (Chunk == NULL) - { - // Internal error - return false; - } - if (Chunk->IsValid()) - { - // Already loaded - return true; - } - if (Chunk->HasLoadFailed()) - { - // Already tried loading and it failed - return false; - } - } - return m_World->GetStorage().LoadChunk(a_ChunkX, a_ChunkZ); -} - - - - - -/// Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() -void cChunkMap::LoadChunks(const cChunkCoordsList & a_Chunks) -{ - for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) - { - LoadChunk(itr->m_ChunkX, itr->m_ChunkZ); - } // for itr - a_Chunks[] -} - - - - - void cChunkMap::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 8c564d0de..7354536d4 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -133,6 +133,9 @@ public: /** Copies the chunk's blocktypes into a_Blocks; returns true if successful */ bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blocks); + /** Returns true iff the chunk is in the loader / generator queue. */ + bool IsChunkQueued(int a_ChunkX, int a_ChunkZ); + bool IsChunkValid (int a_ChunkX, int a_ChunkZ); bool HasChunkAnyClients (int a_ChunkX, int a_ChunkZ); int GetHeight (int a_BlockX, int a_BlockZ); // Waits for the chunk to get loaded / generated @@ -278,12 +281,6 @@ public: /** Touches the chunk, causing it to be loaded or generated */ void TouchChunk(int a_ChunkX, int a_ChunkZ); - /** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */ - bool LoadChunk(int a_ChunkX, int a_ChunkZ); - - /** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */ - void LoadChunks(const cChunkCoordsList & a_Chunks); - /** Marks the chunk as failed-to-load */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 4fa9729ec..d8dbb4a3a 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -283,7 +283,8 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ) { ASSERT(m_PluginInterface != NULL); ASSERT(m_ChunkSink != NULL); - + ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ)); + cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ); m_PluginInterface->CallHookChunkGenerating(ChunkDesc); m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc); diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index e880a6766..190d9e616 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -106,6 +106,10 @@ public: If this callback returns false, the chunk is not generated. */ virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) = 0; + + /** Called to check whether the specified chunk is in the queued state. + Currently used only in Debug-mode asserts. */ + virtual bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) = 0; } ; diff --git a/src/World.cpp b/src/World.cpp index 2a3336dee..e669f6fa0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2374,6 +2374,8 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkZ) void cWorld::QueueSetChunkData(const cSetChunkDataPtr & a_SetChunkData) { + ASSERT(IsChunkQueued(a_SetChunkData->GetChunkX(), a_SetChunkData->GetChunkZ())); + // Validate biomes, if needed: if (!a_SetChunkData->AreBiomesValid()) { @@ -2463,6 +2465,15 @@ bool cWorld::GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockT +bool cWorld::IsChunkQueued(int a_ChunkX, int a_ChunkZ) const +{ + return m_ChunkMap->IsChunkQueued(a_ChunkX, a_ChunkZ); +} + + + + + bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkZ) const { return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkZ); @@ -2787,24 +2798,6 @@ void cWorld::TouchChunk(int a_ChunkX, int a_ChunkZ) -bool cWorld::LoadChunk(int a_ChunkX, int a_ChunkZ) -{ - return m_ChunkMap->LoadChunk(a_ChunkX, a_ChunkZ); -} - - - - - -void cWorld::LoadChunks(const cChunkCoordsList & a_Chunks) -{ - m_ChunkMap->LoadChunks(a_Chunks); -} - - - - - void cWorld::ChunkLoadFailed(int a_ChunkX, int a_ChunkZ) { m_ChunkMap->ChunkLoadFailed(a_ChunkX, a_ChunkZ); @@ -3520,6 +3513,15 @@ bool cWorld::cChunkGeneratorCallbacks::IsChunkValid(int a_ChunkX, int a_ChunkZ) +bool cWorld::cChunkGeneratorCallbacks::IsChunkQueued(int a_ChunkX, int a_ChunkZ) +{ + return m_World->IsChunkQueued(a_ChunkX, a_ChunkZ); +} + + + + + bool cWorld::cChunkGeneratorCallbacks::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) { return m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ); diff --git a/src/World.h b/src/World.h index 49932ac9d..6316c6811 100644 --- a/src/World.h +++ b/src/World.h @@ -279,7 +279,12 @@ public: /** Gets the chunk's blocks, only the block types */ bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes); - bool IsChunkValid (int a_ChunkX, int a_ChunkZ) const; + /** Returns true iff the chunk is in the loader / generator queue. */ + bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const; + + /** Returns true iff the chunk is present and valid. */ + bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const; + bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const; /** Queues a task to unload unused chunks onto the tick thread. The prefferred way of unloading*/ @@ -358,12 +363,6 @@ public: /** Touches the chunk, causing it to be loaded or generated */ void TouchChunk(int a_ChunkX, int a_ChunkZ); - /** Loads the chunk, if not already loaded. Doesn't generate. Returns true if chunk valid (even if already loaded before) */ - bool LoadChunk(int a_ChunkX, int a_ChunkZ); - - /** Loads the chunks specified. Doesn't report failure, other than chunks being !IsValid() */ - void LoadChunks(const cChunkCoordsList & a_Chunks); - /** Marks the chunk as failed-to-load: */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); @@ -822,6 +821,7 @@ private: virtual void OnChunkGenerated (cChunkDesc & a_ChunkDesc) override; virtual bool IsChunkValid (int a_ChunkX, int a_ChunkZ) override; virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) override; + virtual bool IsChunkQueued (int a_ChunkX, int a_ChunkZ) override; // cPluginInterface overrides: virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) override; diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 667a28470..899b0beb3 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -143,6 +143,8 @@ size_t cWorldStorage::GetSaveQueueLength(void) void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate) { + ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ)); + m_LoadQueue.EnqueueItem(sChunkLoad(a_ChunkX, a_ChunkZ, a_Generate)); m_Event.Set(); } @@ -153,6 +155,8 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate) void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkZ) { + ASSERT(m_World->IsChunkValid(a_ChunkX, a_ChunkZ)); + m_SaveQueue.EnqueueItemIfNotPresent(cChunkCoords(a_ChunkX, a_ChunkZ)); m_Event.Set(); } @@ -244,6 +248,7 @@ bool cWorldStorage::LoadOneChunk(void) { sChunkLoad ToLoad(0, 0, false); bool ShouldLoad = m_LoadQueue.TryDequeueItem(ToLoad); + if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ)) { if (ToLoad.m_Generate) @@ -285,11 +290,7 @@ bool cWorldStorage::SaveOneChunk(void) bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { - if (m_World->IsChunkValid(a_ChunkX, a_ChunkZ)) - { - // Already loaded (can happen, since the queue is async) - return true; - } + ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ)); cChunkCoords Coords(a_ChunkX, a_ChunkZ); -- cgit v1.2.3 From 4230eb3d924a2230a20e5044dfffa118ad090429 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 22:55:39 +0200 Subject: Fixed loading empty chunks. Reported on the Dropper map in #1307. --- src/SetChunkData.cpp | 1 - src/WorldStorage/WSSAnvil.cpp | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index bfe59fbcb..707dfb9e8 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -44,7 +44,6 @@ cSetChunkData::cSetChunkData( // Check the params' validity: ASSERT(a_BlockTypes != NULL); ASSERT(a_BlockMetas != NULL); - ASSERT(a_Biomes != NULL); // Copy block types and metas: memcpy(m_BlockTypes, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index b8f8ba019..f78ee405b 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -323,7 +323,13 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT return false; } int Sections = a_NBT.FindChildByName(Level, "Sections"); - if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound)) + if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List)) + { + LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); + return false; + } + eTagType SectionsType = a_NBT.GetChildrenType(Sections); + if ((SectionsType != TAG_Compound) && (SectionsType != TAG_End)) { LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; -- cgit v1.2.3 From 103fa8812d6bb0fcd996d1d75817d657a0a2691c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 5 Sep 2014 23:26:00 +0200 Subject: WorldStorage no longer queues chunks into generator. --- src/ChunkMap.cpp | 4 ++-- src/Generating/ChunkGenerator.cpp | 2 ++ src/WorldStorage/WorldStorage.cpp | 23 +++++++---------------- src/WorldStorage/WorldStorage.h | 39 ++++++--------------------------------- 4 files changed, 17 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 50066e539..9c105c5af 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -163,7 +163,7 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) { Chunk->SetPresence(cChunk::cpQueued); Chunk->SetShouldGenerateIfLoadFailed(true); - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, true); + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ); } return Chunk; } @@ -191,7 +191,7 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) if (!Chunk->IsValid() && !Chunk->IsQueued()) { Chunk->SetPresence(cChunk::cpQueued); - m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ, false); + m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ); } return Chunk; diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index d8dbb4a3a..d615456c1 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -112,6 +112,8 @@ void cChunkGenerator::Stop(void) void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate) { + ASSERT(m_ChunkSink->IsChunkQueued(a_ChunkX, a_ChunkZ)); + { cCSLock Lock(m_CS); diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 899b0beb3..179cf9393 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -141,11 +141,11 @@ size_t cWorldStorage::GetSaveQueueLength(void) -void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate) +void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ)); - m_LoadQueue.EnqueueItem(sChunkLoad(a_ChunkX, a_ChunkZ, a_Generate)); + m_LoadQueue.EnqueueItem(cChunkCoords(a_ChunkX, a_ChunkZ)); m_Event.Set(); } @@ -167,7 +167,7 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkZ) void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkZ) { - m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkZ, true)); + m_LoadQueue.Remove(cChunkCoords(a_ChunkX, a_ChunkZ)); } @@ -246,23 +246,14 @@ void cWorldStorage::Execute(void) bool cWorldStorage::LoadOneChunk(void) { - sChunkLoad ToLoad(0, 0, false); + cChunkCoords ToLoad(0, 0); bool ShouldLoad = m_LoadQueue.TryDequeueItem(ToLoad); - if (ShouldLoad && !LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ)) + if (ShouldLoad) { - if (ToLoad.m_Generate) - { - // The chunk couldn't be loaded, generate it: - m_World->GetGenerator().QueueGenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ, false); - } - else - { - // TODO: Notify the world that the load has failed: - // m_World->ChunkLoadFailed(ToLoad.m_ChunkX, ToLoad.m_ChunkZ); - } + return LoadChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ); } - return ShouldLoad; + return false; } diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index 5f89ead53..fc7e9f84c 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -64,12 +64,9 @@ public: cWorldStorage(void); ~cWorldStorage(); - void QueueLoadChunk(int a_ChunkX, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true + void QueueLoadChunk(int a_ChunkX, int a_ChunkZ); void QueueSaveChunk(int a_ChunkX, int a_ChunkZ); - /// Loads the chunk specified; returns true on success, false on failure - bool LoadChunk(int a_ChunkX, int a_ChunkZ); - void UnqueueLoad(int a_ChunkX, int a_ChunkZ); void UnqueueSave(const cChunkCoords & a_Chunk); @@ -84,38 +81,10 @@ public: protected: - struct sChunkLoad - { - int m_ChunkX; - int m_ChunkZ; - bool m_Generate; // If true, the chunk will be generated if it cannot be loaded - - sChunkLoad(int a_ChunkX, int a_ChunkZ, bool a_Generate) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), m_Generate(a_Generate) {} - - bool operator ==(const sChunkLoad other) const - { - return ( - (this->m_ChunkX == other.m_ChunkX) && - (this->m_ChunkZ == other.m_ChunkZ) - ); - } - } ; - - struct FuncTable - { - static void Delete(sChunkLoad) {} - static void Combine(sChunkLoad & a_orig, const sChunkLoad a_new) - { - a_orig.m_Generate |= a_new.m_Generate; - } - }; - - typedef cQueue sChunkLoadQueue; - cWorld * m_World; AString m_StorageSchemaName; - sChunkLoadQueue m_LoadQueue; + cChunkCoordsQueue m_LoadQueue; cChunkCoordsQueue m_SaveQueue; /// All the storage schemas (all used for loading) @@ -123,7 +92,11 @@ protected: /// The one storage schema used for saving cWSSchema * m_SaveSchema; + + /// Loads the chunk specified; returns true on success, false on failure + bool LoadChunk(int a_ChunkX, int a_ChunkZ); + void InitSchemas(int a_StorageCompressionFactor); virtual void Execute(void) override; -- cgit v1.2.3 From 15d4e543b1bcc56923b2f94bf0a63b6ed8cc8edc Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 6 Sep 2014 09:56:22 +0100 Subject: Xoft fixes. --- src/WebAdmin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WebAdmin.h b/src/WebAdmin.h index d6baa2ef9..94b95dbcf 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -150,7 +150,7 @@ public: static AString GetBaseURL(const AStringVector & a_URLSplit); /** Returns the content type from the file extension. If the extension isn't in the list, the function returns "text/html" */ - AString GetContentTypeFromFileExt(const AString & a_FileExtension); + static AString GetContentTypeFromFileExt(const AString & a_FileExtension); protected: /** Common base class for request body data handlers */ -- cgit v1.2.3 From dd0aa22d2e5720aac5df473382c3ddaa1ca7e484 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 13:11:08 +0200 Subject: Fixed scoreboard loader type checks. Fixes scoreboard loading error reported on the Dropper map in #1307. --- src/WorldStorage/ScoreboardSerializer.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index da8236e0d..e30eecf67 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -283,37 +283,37 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) bool AllowsFriendlyFire = true, CanSeeFriendlyInvisible = false; int CurrLine = a_NBT.FindChildByName(Child, "Name"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { - Name = a_NBT.GetInt(CurrLine); + Name = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "DisplayName"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { - DisplayName = a_NBT.GetInt(CurrLine); + DisplayName = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Prefix"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { - Prefix = a_NBT.GetInt(CurrLine); + Prefix = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "Suffix"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_String)) { - Suffix = a_NBT.GetInt(CurrLine); + Suffix = a_NBT.GetString(CurrLine); } CurrLine = a_NBT.FindChildByName(Child, "AllowFriendlyFire"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { AllowsFriendlyFire = (a_NBT.GetInt(CurrLine) != 0); } CurrLine = a_NBT.FindChildByName(Child, "SeeFriendlyInvisibles"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { CanSeeFriendlyInvisible = (a_NBT.GetInt(CurrLine) != 0); } -- cgit v1.2.3 From 9f9302f470d2adc1ef4018474c4f03a72ca723ed Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 13:32:16 +0200 Subject: Anvil: Fixed an off-by-one error in the loader. Fixes #1307. --- src/WorldStorage/WSSAnvil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index f78ee405b..2500b5dea 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2821,7 +2821,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a } unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]); unsigned ChunkOffset = ChunkLocation >> 8; - if (ChunkOffset <= 2) + if (ChunkOffset < 2) { return false; } -- cgit v1.2.3 From 9e1f67932b32241312f25279d924c235d4cff66d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 15:26:20 +0200 Subject: Fixed player spawning in unknown world. This may happen if the admin removes a world. --- src/Entities/Player.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 51a1f8699..b0da6965a 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1671,6 +1671,10 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) m_LoadedWorldName = root.get("world", "world").asString(); a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), false); + if (a_World == NULL) + { + a_World = cRoot::Get()->GetDefaultWorld(); + } m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); -- cgit v1.2.3 From 868723ce507eb7092fea4852c3a8f78d7391ed7c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 18:57:57 +0200 Subject: Alpha-sorted protocol 1.7 senders. --- src/Protocol/Protocol17x.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index ccfa19eb6..d3100d0fb 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -71,7 +71,9 @@ public: virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendEntityHeadLook (const cEntity & a_Entity) override; @@ -82,6 +84,8 @@ public: virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; virtual void SendGameMode (eGameMode a_GameMode) override; virtual void SendHealth (void) override; @@ -93,10 +97,9 @@ public: virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; @@ -105,12 +108,9 @@ public: virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; -- cgit v1.2.3 From 0a651b9fd83f078a73429f02603144e80a05148d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 18:59:17 +0200 Subject: Added Y-wise asserts to signs. This should help detect #1313's second case. --- src/BlockEntities/SignEntity.cpp | 1 + src/Protocol/Protocol17x.cpp | 1 + src/WorldStorage/WSSAnvil.cpp | 2 ++ 3 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/BlockEntities/SignEntity.cpp b/src/BlockEntities/SignEntity.cpp index 97fed0f04..23d9ef926 100644 --- a/src/BlockEntities/SignEntity.cpp +++ b/src/BlockEntities/SignEntity.cpp @@ -15,6 +15,7 @@ cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) : super(a_BlockType, a_X, a_Y, a_Z, a_World) { + ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 1091b877f..f24ef320d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1355,6 +1355,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) void cProtocol172::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { ASSERT(m_State == 3); // In game mode? + ASSERT((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)); cPacketizer Pkt(*this, 0x33); Pkt.WriteInt(a_BlockX); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 2500b5dea..fe309ce4e 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -623,6 +623,8 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { + ASSERT((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)); + // Load the specific BlockEntity type: switch (a_BlockType) { -- cgit v1.2.3 From e1a9a6291b98126dad993009bb184c963bd9765b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 6 Sep 2014 19:01:30 +0200 Subject: Removed chunk's unused Y coord. This fixes the second issue of #1313. --- src/Chunk.cpp | 6 +++--- src/Chunk.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index caace5024..99e48df95 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1345,11 +1345,11 @@ void cChunk::CreateBlockEntities(void) case E_BLOCK_JUKEBOX: case E_BLOCK_FLOWER_POT: { - if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) + if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width)) { m_BlockEntities.push_back(cBlockEntity::CreateByBlockType( BlockType, GetMeta(x, y, z), - x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width, m_World + x + m_PosX * Width, y, z + m_PosZ * Width, m_World )); } break; @@ -3178,7 +3178,7 @@ void cChunk::PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ, int & a Vector3i cChunk::PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ) { - return Vector3i(m_PosX * Width + a_RelX, m_PosY * Height + a_RelY, m_PosZ * Width + a_RelZ); + return Vector3i(m_PosX * Width + a_RelX, a_RelY, m_PosZ * Width + a_RelZ); } diff --git a/src/Chunk.h b/src/Chunk.h index 81862f2e7..f282694c2 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -160,7 +160,6 @@ public: void TickBlock(int a_RelX, int a_RelY, int a_RelZ); int GetPosX(void) const { return m_PosX; } - int GetPosY(void) const { return m_PosY; } int GetPosZ(void) const { return m_PosZ; } cWorld * GetWorld(void) const { return m_World; } @@ -483,7 +482,7 @@ private: /** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */ int m_StayCount; - int m_PosX, m_PosY, m_PosZ; + int m_PosX, m_PosZ; cWorld * m_World; cChunkMap * m_ChunkMap; -- cgit v1.2.3 From a0feff2734d7591bf4feddbe60145643bdae53df Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Sep 2014 19:42:35 +0200 Subject: WebAdmin: Added HTTPS instructions when cert / key is missing. --- src/HTTPServer/HTTPServer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index 8eabe5cb2..c91be677e 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -171,6 +171,7 @@ bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_Port if (m_Cert.get() == NULL) { LOGWARNING("WebServer: The server is running in unsecure HTTP mode."); + LOGINFO("Put a valid HTTPS certificate to file 'webadmin/httpscert.crt' and its corresponding private key to 'httpskey.pem' (without any password) to enable HTTPS support"); } else { -- cgit v1.2.3 From d2c1518145932bf6ef3cf30feac8d5698a77bf7e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Sep 2014 19:45:15 +0200 Subject: Webadmin: Added default ports to auto-generated ini file. Fixes #1382. --- src/WebAdmin.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 341c64236..db2ace386 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -43,6 +43,8 @@ public: cWebAdmin::cWebAdmin(void) : m_IsInitialized(false), m_IsRunning(false), + m_PortsIPv4("8080"), + m_PortsIPv6(""), m_TemplateScript("") { } @@ -89,6 +91,8 @@ bool cWebAdmin::Init(void) m_IniFile.AddHeaderComment(" Password format: Password=*password*; for example:"); m_IniFile.AddHeaderComment(" [User:admin]"); m_IniFile.AddHeaderComment(" Password=admin"); + m_IniFile.SetValue("WebAdmin", "Port", m_PortsIPv4); + m_IniFile.SetValue("WebAdmin", "PortsIPv6", m_PortsIPv6); m_IniFile.WriteFile("webadmin.ini"); } @@ -100,8 +104,8 @@ bool cWebAdmin::Init(void) LOGD("Initialising WebAdmin..."); - m_PortsIPv4 = m_IniFile.GetValueSet("WebAdmin", "Port", "8080"); - m_PortsIPv6 = m_IniFile.GetValueSet("WebAdmin", "PortsIPv6", ""); + m_PortsIPv4 = m_IniFile.GetValueSet("WebAdmin", "Port", m_PortsIPv4); + m_PortsIPv6 = m_IniFile.GetValueSet("WebAdmin", "PortsIPv6", m_PortsIPv6); if (!m_HTTPServer.Initialize(m_PortsIPv4, m_PortsIPv6)) { -- cgit v1.2.3 From c5cd75fae83a61920a9a5d50b94b09ae25d87430 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 7 Sep 2014 22:35:22 +0200 Subject: Exported cClientHandle:GetIPString() to Lua API. --- src/ClientHandle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 593d0780d..74e89deee 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -62,7 +62,7 @@ public: cClientHandle(const cSocket * a_Socket, int a_ViewDistance); virtual ~cClientHandle(); - const AString & GetIPString(void) const { return m_IPString; } + const AString & GetIPString(void) const { return m_IPString; } // tolua_export cPlayer * GetPlayer(void) { return m_Player; } // tolua_export -- cgit v1.2.3 From 09ff17b71ea5659dc628d9d6e3f1fd308d10037a Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 00:36:30 +0200 Subject: Implemented packet compression. ChunkData packet needs this. --- src/Protocol/ChunkDataSerializer.cpp | 83 +++++++++++++++++++++++++++--------- src/Protocol/ChunkDataSerializer.h | 4 +- src/Protocol/Protocol125.cpp | 2 +- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol17x.cpp | 26 ++++++++++- src/Protocol/Protocol18x.cpp | 34 ++++++++++----- src/Protocol/Protocol18x.h | 1 + 7 files changed, 117 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 29e32ce32..a2e0c9ef9 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -8,6 +8,7 @@ #include "Globals.h" #include "ChunkDataSerializer.h" #include "zlib/zlib.h" +#include "ByteBuffer.h" @@ -30,7 +31,7 @@ cChunkDataSerializer::cChunkDataSerializer( -const AString & cChunkDataSerializer::Serialize(int a_Version) +const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int a_ChunkZ) { Serializations::const_iterator itr = m_Serializations.find(a_Version); if (itr != m_Serializations.end()) @@ -43,7 +44,7 @@ const AString & cChunkDataSerializer::Serialize(int a_Version) { case RELEASE_1_2_5: Serialize29(data); break; case RELEASE_1_3_2: Serialize39(data); break; - case RELEASE_1_8_0: Serialize80(data); break; + case RELEASE_1_8_0: Serialize80(data, a_ChunkX, a_ChunkZ); break; // TODO: Other protocol versions may serialize the data differently; implement here default: @@ -176,45 +177,87 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) -void cChunkDataSerializer::Serialize80(AString & a_Data) +void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_ChunkZ) { // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) // Blocktypes converter (1.8 included the meta into the blocktype): - unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)]; + /*unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)]; for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++) { BLOCKTYPE BlockType = m_BlockTypes[Index]; NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta); - } + }*/ const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; - const int BlockLightOffset = sizeof(Blocks); + const int MetadataOffset = sizeof(m_BlockTypes); + const int BlockLightOffset = MetadataOffset + sizeof(m_BlockMetas); const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight); const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight); const int DataSize = BiomeOffset + BiomeDataSize; // Temporary buffer for the composed data: char AllData [DataSize]; - memcpy(AllData, Blocks, sizeof(Blocks)); + memcpy(AllData, m_BlockTypes, sizeof(m_BlockTypes)); + memcpy(AllData + MetadataOffset, m_BlockMetas, sizeof(m_BlockMetas)); memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight)); memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight)); memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize); - // Put all those data into a_Data: - a_Data.push_back('\x01'); // "Ground-up continuous", or rather, "biome data present" flag - - // Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively - // Also, no endian flipping is needed because of the const values - unsigned short BitMap = 0xffff; - a_Data.append((const char *)&BitMap, sizeof(unsigned short)); - - // Write chunk size: - UInt32 ChunkSize = htonl((UInt32)DataSize); - a_Data.append((const char *)&ChunkSize, 4); - - a_Data.append(AllData, DataSize); // Chunk data + cByteBuffer Packet(512 KiB); + Packet.WriteVarInt(0x21); // Packet id (Chunk Data packet) + Packet.WriteBEInt(a_ChunkX); + Packet.WriteBEInt(a_ChunkZ); + Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag + Packet.WriteBEShort(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff + Packet.WriteVarInt(DataSize); // Chunk size + Packet.WriteBuf(AllData, DataSize); // Chunk data + + AString PacketData; + Packet.ReadAll(PacketData); + Packet.CommitRead(); + + cByteBuffer NumberBuffer(20); + if (PacketData.size() >= 256) + { + AString PostData; + NumberBuffer.WriteVarInt(PacketData.size()); + NumberBuffer.ReadAll(PostData); + NumberBuffer.CommitRead(); + + // Compress the data: + const uLongf CompressedMaxSize = 200000; + char CompressedData[CompressedMaxSize]; + + uLongf CompressedSize = compressBound(PacketData.size()); + // Run-time check that our compile-time guess about CompressedMaxSize was enough: + ASSERT(CompressedSize <= CompressedMaxSize); + compress2((Bytef*)CompressedData, &CompressedSize, (const Bytef*)PacketData.data(), PacketData.size(), Z_DEFAULT_COMPRESSION); + + NumberBuffer.WriteVarInt(CompressedSize + PostData.size()); + NumberBuffer.WriteVarInt(PacketData.size()); + NumberBuffer.ReadAll(PostData); + NumberBuffer.CommitRead(); + + a_Data.clear(); + a_Data.resize(PostData.size() + CompressedSize); + a_Data.append(PostData.data(), PostData.size()); + a_Data.append(CompressedData, CompressedSize); + } + else + { + AString PostData; + NumberBuffer.WriteVarInt(Packet.GetUsedSpace() + 1); + NumberBuffer.WriteVarInt(0); + NumberBuffer.ReadAll(PostData); + NumberBuffer.CommitRead(); + + a_Data.clear(); + a_Data.resize(PostData.size() + PacketData.size()); + a_Data.append(PostData.data(), PostData.size()); + a_Data.append(PacketData.data(), PacketData.size()); + } } diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index 4c33aede1..3caa89d41 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -24,7 +24,7 @@ protected: void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5 void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10 - void Serialize80(AString & a_Data); // Release 1.8 + void Serialize80(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8 public: enum @@ -42,7 +42,7 @@ public: const unsigned char * a_BiomeData ); - const AString & Serialize(int a_Version); // Returns one of the internal m_Serializations[] + const AString & Serialize(int a_Version, int a_ChunkX, int a_ChunkZ); // Returns one of the internal m_Serializations[] } ; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index a66c64309..a74be28a5 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -262,7 +262,7 @@ void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize SendPreChunk(a_ChunkX, a_ChunkZ, true); // Send the chunk data: - AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_2_5); + AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_2_5, a_ChunkX, a_ChunkZ); WriteByte(PACKET_MAP_CHUNK); WriteInt (a_ChunkX); WriteInt (a_ChunkZ); diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 5c58ab0ba..5fd2655b8 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -176,7 +176,7 @@ void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize // Pre-chunk not used in 1.3.2. Finally. // Send the chunk data: - AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2); + AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ); WriteByte(PACKET_CHUNK_DATA); WriteInt (a_ChunkX); WriteInt (a_ChunkZ); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index b4f30b639..0bee40028 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -346,7 +346,7 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize // Serialize first, before creating the Packetizer (the packetizer locks a CS) // This contains the flags and bitmasks, too - const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2); + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ); cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteInt(a_ChunkX); @@ -1533,6 +1533,17 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) // Write one NUL extra, so that we can detect over-reads bb.Write("\0", 1); + // 1.8 - Compressed packets + if (m_State == 3) + { + UInt32 CompressedSize; + if (!bb.ReadVarInt(CompressedSize)) + { + // Not enough data + break; + } + } + UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) { @@ -2511,10 +2522,23 @@ cProtocol172::cPacketizer::~cPacketizer() // Send the packet length UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace(); + if (m_Protocol.m_State == 3) + { + PacketLen += 1; + } + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); m_Protocol.SendData(DataToSend.data(), DataToSend.size()); m_Protocol.m_OutPacketLenBuffer.CommitRead(); + + if (m_Protocol.m_State == 3) + { + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); + m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); + m_Protocol.SendData(DataToSend.data(), DataToSend.size()); + m_Protocol.m_OutPacketLenBuffer.CommitRead(); + } // Send the packet data: m_Out.ReadAll(DataToSend); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index a3e72d4dd..bcb5c2036 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -13,6 +13,7 @@ Implements the 1.8.x protocol classes: #include "json/json.h" #include "ChunkDataSerializer.h" #include "Protocol18x.h" +#include "zlib/zlib.h" #include "../ClientHandle.h" #include "../CompositeChat.h" @@ -21,7 +22,7 @@ Implements the 1.8.x protocol classes: #include "../World.h" #include "../Entities/Player.h" -#include "Entities/Painting.h" +#include "../Entities/Painting.h" @@ -57,23 +58,38 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd +void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x28); // Effect packet + Pkt.WriteInt(a_EffectID); + Pkt.WritePosition(Vector3i(a_SrcX, a_SrcY, a_SrcZ)); + Pkt.WriteInt(a_Data); + Pkt.WriteBool(false); +} + + + + + void cProtocol180::SendLoginSuccess(void) { ASSERT(m_State == 2); // State: login? - // Disable compression: + // Enable compression: { cPacketizer Pkt(*this, 0x03); // Set compression packet - Pkt.WriteVarInt(-1); + Pkt.WriteVarInt(256); } + m_State = 3; // State = Game + { cPacketizer Pkt(*this, 0x02); // Login success packet Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); Pkt.WriteString(m_Client->GetUsername()); } - - m_State = 3; // State = Game } @@ -409,12 +425,10 @@ void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize // Serialize first, before creating the Packetizer (the packetizer locks a CS) // This contains the flags and bitmasks, too - const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0); + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ); - cPacketizer Pkt(*this, 0x21); // Chunk Data packet - Pkt.WriteInt(a_ChunkX); - Pkt.WriteInt(a_ChunkZ); - Pkt.WriteBuf(ChunkData.data(), ChunkData.size()); + cCSLock Lock(m_CSPacket); + SendData(ChunkData.data(), ChunkData.size()); } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 5c6111958..d64742939 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -54,6 +54,7 @@ public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendLoginSuccess (void) override; virtual void SendPlayerAbilities (void) override {} virtual void SendWindowClose (const cWindow & a_Window) override {} -- cgit v1.2.3 From 10a30a03e38116fe084138662bd59147331dd883 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 11:35:21 +0200 Subject: Added GetProtocolVersion() to cProtocol. --- src/Protocol/Protocol.h | 7 ++++++- src/Protocol/Protocol125.cpp | 3 ++- src/Protocol/Protocol132.cpp | 2 ++ src/Protocol/Protocol14x.cpp | 9 +++------ src/Protocol/Protocol17x.cpp | 26 ++++++++++++-------------- src/Protocol/Protocol17x.h | 1 - src/Protocol/Protocol18x.cpp | 3 ++- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- 8 files changed, 29 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8e1842ec1..5811e5bff 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -46,7 +46,8 @@ typedef unsigned char Byte; class cProtocol { public: - cProtocol(cClientHandle * a_Client) : + cProtocol(cClientHandle * a_Client, int a_ProtocolVersion) : + m_ProtocolVersion(a_ProtocolVersion), m_Client(a_Client) { } @@ -130,7 +131,11 @@ public: /// Returns the ServerID used for authentication through session.minecraft.net virtual AString GetAuthServerID(void) = 0; + /** Returns the protocol version of this protocol. */ + int GetProtocolVersion(void) const { return m_ProtocolVersion; } + protected: + int m_ProtocolVersion; cClientHandle * m_Client; cCriticalSection m_CSPacket; // Each SendXYZ() function must acquire this CS in order to send the whole packet at once diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index a74be28a5..77939d933 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -16,6 +16,7 @@ Documentation: #include "../ClientHandle.h" #include "../World.h" #include "ChunkDataSerializer.h" +#include "ProtocolRecognizer.h" #include "../Entities/Entity.h" #include "../Entities/ExpOrb.h" #include "../Mobs/Monster.h" @@ -132,7 +133,7 @@ typedef unsigned char Byte; cProtocol125::cProtocol125(cClientHandle * a_Client) : - super(a_Client), + super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_2_5), m_ReceivedData(32 KiB), m_LastSentDimension(dimNotSet) { diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 5fd2655b8..6fbc3a264 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "ChunkDataSerializer.h" +#include "ProtocolRecognizer.h" #include "Protocol132.h" #include "../Root.h" #include "../Server.h" @@ -78,6 +79,7 @@ cProtocol132::cProtocol132(cClientHandle * a_Client) : super(a_Client), m_IsEncrypted(false) { + m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_3_2; } diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp index 3b6b6a42a..2d737acb4 100644 --- a/src/Protocol/Protocol14x.cpp +++ b/src/Protocol/Protocol14x.cpp @@ -23,6 +23,7 @@ Implements the 1.4.x protocol classes representing these protocols: #include "../UI/Window.h" #include "../Entities/Pickup.h" #include "../Entities/FallingBlock.h" +#include "ProtocolRecognizer.h" #ifdef _MSC_VER #pragma warning(push) @@ -72,6 +73,7 @@ enum cProtocol142::cProtocol142(cClientHandle * a_Client) : super(a_Client) { + m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_4_2; } @@ -132,12 +134,6 @@ void cProtocol142::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { - if (!a_DoDaylightCycle) - { - // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. - a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); - } - cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_TIME); WriteInt64(a_WorldAge); @@ -156,6 +152,7 @@ void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do cProtocol146::cProtocol146(cClientHandle * a_Client) : super(a_Client) { + m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_4_6; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 0bee40028..e34a61818 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -12,6 +12,7 @@ Implements the 1.7.x protocol classes: #include "Globals.h" #include "json/json.h" #include "Protocol17x.h" +#include "ProtocolRecognizer.h" #include "ChunkDataSerializer.h" #include "PolarSSL++/Sha1Checksum.h" @@ -92,7 +93,7 @@ extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; // cProtocol172: cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client), + super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_7_2), m_ServerAddress(a_ServerAddress), m_ServerPort(a_ServerPort), m_State(a_State), @@ -1534,7 +1535,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) bb.Write("\0", 1); // 1.8 - Compressed packets - if (m_State == 3) + if ((m_State == 3) && (GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)) { UInt32 CompressedSize; if (!bb.ReadVarInt(CompressedSize)) @@ -2522,23 +2523,19 @@ cProtocol172::cPacketizer::~cPacketizer() // Send the packet length UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace(); - if (m_Protocol.m_State == 3) + + if ((m_Protocol.m_State == 3) && (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)) { - PacketLen += 1; + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen + 1); + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); + } + else + { + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); } - - m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); m_Protocol.SendData(DataToSend.data(), DataToSend.size()); m_Protocol.m_OutPacketLenBuffer.CommitRead(); - - if (m_Protocol.m_State == 3) - { - m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); - m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); - m_Protocol.SendData(DataToSend.data(), DataToSend.size()); - m_Protocol.m_OutPacketLenBuffer.CommitRead(); - } // Send the packet data: m_Out.ReadAll(DataToSend); @@ -3080,6 +3077,7 @@ void cProtocol172::cPacketizer::WriteEntityProperties(const cEntity & a_Entity) cProtocol176::cProtocol176(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { + m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_7_6; } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index d715e1cec..289545bc7 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -211,7 +211,6 @@ protected: } void WriteItem(const cItem & a_Item); - void WriteItem180(const cItem & a_Item); void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index bcb5c2036..302fcc836 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -12,8 +12,8 @@ Implements the 1.8.x protocol classes: #include "Bindings/PluginManager.h" #include "json/json.h" #include "ChunkDataSerializer.h" +#include "ProtocolRecognizer.h" #include "Protocol18x.h" -#include "zlib/zlib.h" #include "../ClientHandle.h" #include "../CompositeChat.h" @@ -52,6 +52,7 @@ class cProtocol176; cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { + m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_8_0; } diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 642e96880..c535390cc 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -26,7 +26,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : - super(a_Client), + super(a_Client, 0), m_Protocol(NULL), m_Buffer(512) { @@ -915,7 +915,7 @@ bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void) m_Protocol = new cProtocol132(m_Client); return true; } - case PROTO_VERSION_1_4_2: + //case PROTO_VERSION_1_4_2: case PROTO_VERSION_1_4_4: { m_Protocol = new cProtocol142(m_Client); -- cgit v1.2.3 From 38124bcce3c5e8ed8e4dba904dc4f15f89a82c14 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 12:24:06 +0200 Subject: Updated chunk sending to 1.8 --- src/Protocol/ChunkDataSerializer.cpp | 17 +++++++++-------- src/Protocol/Protocol17x.cpp | 12 ++++++------ src/Protocol/Protocol18x.cpp | 17 +++++++---------- src/Protocol/Protocol18x.h | 2 -- 4 files changed, 22 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index a2e0c9ef9..d4574954e 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -182,25 +182,26 @@ void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_Chu // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) // Blocktypes converter (1.8 included the meta into the blocktype): - /*unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)]; + unsigned char Blocks[cChunkDef::NumBlocks * 2]; + size_t LastOffset = 0; for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++) { - BLOCKTYPE BlockType = m_BlockTypes[Index]; + BLOCKTYPE BlockType = m_BlockTypes[Index] & 0xFF; NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; - Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta); - }*/ + Blocks[LastOffset] = (BlockType << 4) | ((unsigned char)BlockMeta); + Blocks[LastOffset + 1] = (unsigned char)BlockType >> 4; + LastOffset += 2; + } const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; - const int MetadataOffset = sizeof(m_BlockTypes); - const int BlockLightOffset = MetadataOffset + sizeof(m_BlockMetas); + const int BlockLightOffset = sizeof(Blocks); const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight); const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight); const int DataSize = BiomeOffset + BiomeDataSize; // Temporary buffer for the composed data: char AllData [DataSize]; - memcpy(AllData, m_BlockTypes, sizeof(m_BlockTypes)); - memcpy(AllData + MetadataOffset, m_BlockMetas, sizeof(m_BlockMetas)); + memcpy(AllData, Blocks, sizeof(Blocks)); memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight)); memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight)); memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index e34a61818..34bfbc82b 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1503,14 +1503,14 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) ); m_CommLogFile.Flush(); } - + if (!m_ReceivedData.Write(a_Data, a_Size)) { // Too much data in the incoming queue, report to caller: m_Client->PacketBufferFull(); return; } - + // Handle all complete packets: for (;;) { @@ -1530,10 +1530,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) cByteBuffer bb(PacketLen + 1); VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); m_ReceivedData.CommitRead(); - - // Write one NUL extra, so that we can detect over-reads - bb.Write("\0", 1); - + // 1.8 - Compressed packets if ((m_State == 3) && (GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)) { @@ -1544,6 +1541,9 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) break; } } + + // Write one NUL extra, so that we can detect over-reads + bb.Write("\0", 1); UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 302fcc836..386e3dfb2 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -121,7 +121,7 @@ void cProtocol180::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x08); // Player Position And Look packet + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteDouble(Player->GetPosX()); @@ -131,7 +131,7 @@ void cProtocol180::SendPlayerMoveLook(void) Pkt.WriteDouble(Player->GetPosZ()); Pkt.WriteFloat((float)Player->GetYaw()); Pkt.WriteFloat((float)Player->GetPitch()); - Pkt.WriteByte(0);*/ + Pkt.WriteByte(0); } @@ -168,12 +168,12 @@ void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x12); // Entity Velocity packet + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); - Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400));*/ + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); } @@ -395,9 +395,9 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x3f); + cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); - Pkt.WriteBuf(a_Message.data(), a_Message.size());*/ + Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -672,10 +672,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) - { - return; - } + a_ByteBuffer.ReadAll(Data); m_Client->HandlePluginMessage(Channel, Data); } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index d64742939..d9fd5d573 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -56,8 +56,6 @@ public: virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendLoginSuccess (void) override; - virtual void SendPlayerAbilities (void) override {} - virtual void SendWindowClose (const cWindow & a_Window) override {} virtual void SendPickupSpawn (const cPickup & a_Pickup) override {} virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {} virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override {} -- cgit v1.2.3 From 5f207c8bb799dc5619586c2e885f7a692a97d915 Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 8 Sep 2014 14:57:58 +0100 Subject: If server fails init, save any changed or generated settings. --- src/Root.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index f04cbf08b..a2fbda812 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -151,6 +151,7 @@ void cRoot::Start(void) m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init if (!m_Server->InitServer(IniFile)) { + IniFile.WriteFile("Settings.ini") LOGERROR("Failure starting server, aborting..."); return; } -- cgit v1.2.3 From 4613fabd45e61700271d3dba186cb6564e07284b Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 8 Sep 2014 15:15:31 +0100 Subject: derp --- src/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index a2fbda812..8e88ba1af 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -151,7 +151,7 @@ void cRoot::Start(void) m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init if (!m_Server->InitServer(IniFile)) { - IniFile.WriteFile("Settings.ini") + IniFile.WriteFile("Settings.ini"); LOGERROR("Failure starting server, aborting..."); return; } -- cgit v1.2.3 From 8f8693a71eb896ccc7c14c4033ae8d07dae27ac3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 17:02:54 +0200 Subject: Fixed more 1.8 packets. --- src/ByteBuffer.cpp | 44 ++++++++++ src/ByteBuffer.h | 5 ++ src/ClientHandle.cpp | 33 +++++--- src/Protocol/Protocol17x.cpp | 59 ++++++++----- src/Protocol/Protocol17x.h | 14 ++-- src/Protocol/Protocol18x.cpp | 196 +++++++++++++++++++++++++++++++++++++++++-- src/Protocol/Protocol18x.h | 9 +- 7 files changed, 313 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 96556bf61..94684afb8 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -489,6 +489,24 @@ bool cByteBuffer::ReadLEInt(int & a_Value) +bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) +{ + Int64 Value; + if (!ReadBEInt64(Value)) + { + return false; + } + + a_BlockX = Value >> 38; + a_BlockY = Value << 26 >> 52; + a_BlockZ = Value << 38 >> 38; + return true; +} + + + + + bool cByteBuffer::WriteChar(char a_Value) { CHECK_THREAD; @@ -661,6 +679,15 @@ bool cByteBuffer::WriteLEInt(int a_Value) +bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return WriteBEInt64(((Int64)a_BlockX & 0x3FFFFFF) << 38 | ((Int64)a_BlockY & 0xFFF) << 26 | ((Int64)a_BlockZ & 0x3FFFFFF)); +} + + + + + bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) { CHECK_THREAD; @@ -792,6 +819,23 @@ bool cByteBuffer::SkipRead(size_t a_Count) +bool cByteBuffer::ReverseRead(size_t a_Count) +{ + CHECK_THREAD; + CheckValid(); + if (m_ReadPos < a_Count) + { + return false; + } + + m_ReadPos -= a_Count; + return true; +} + + + + + void cByteBuffer::ReadAll(AString & a_Data) { CHECK_THREAD; diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index adaa00330..e200d2a7b 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -64,6 +64,7 @@ public: bool ReadVarInt (UInt32 & a_Value); bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8 bool ReadLEInt (int & a_Value); + bool ReadPosition (int & a_BlockX, int & a_BlockY, int & a_BlockZ); /** Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...) */ template bool ReadVarInt(T & a_Value) @@ -90,6 +91,7 @@ public: bool WriteVarInt (UInt32 a_Value); bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8 bool WriteLEInt (int a_Value); + bool WritePosition (int a_BlockX, int a_BlockY, int a_BlockZ); /** Reads a_Count bytes into a_Buffer; returns true if successful */ bool ReadBuf(void * a_Buffer, size_t a_Count); @@ -105,6 +107,9 @@ public: /** Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer */ bool SkipRead(size_t a_Count); + + /** Reverse reading by a_Count bytes; returns false if not enough readed bytes in the ringbuffer */ + bool ReverseRead(size_t a_Count); /** Reads all available data into a_Data */ void ReadAll(AString & a_Data); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 4a768771e..4c36dec4d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1198,6 +1198,12 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cWorld * World = m_Player->GetWorld(); + // 1.8 protocol fix + if ((int)a_BlockFace == 255) + { + a_BlockFace = BLOCK_FACE_NONE; + } + if ( (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block ( @@ -1268,22 +1274,25 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e return; } - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); - - if (BlockHandler->IsUseable() && !m_Player->IsCrouched()) + if ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5) { - if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta)) + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); + cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); + + if (BlockHandler->IsUseable() && !m_Player->IsCrouched()) { - // A plugin doesn't agree with using the block, abort + if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta)) + { + // A plugin doesn't agree with using the block, abort + return; + } + cChunkInterface ChunkInterface(World->GetChunkMap()); + BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ); + PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); return; } - cChunkInterface ChunkInterface(World->GetChunkMap()); - BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ); - PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); - return; } short EquippedDamage = Equipped.m_ItemDamage; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 34bfbc82b..9a7111a43 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1567,7 +1567,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() ); } - + if (!HandlePacket(bb, PacketType)) { // Unknown packet, already been reported, but without the length. Log the length here: @@ -1592,7 +1592,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) return; } - + if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error @@ -1613,7 +1613,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) m_Client->PacketError(PacketType); } } // for (ever) - + // Log any leftover bytes into the logfile: if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0)) { @@ -2332,25 +2332,32 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) -void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) +void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata, bool a_IsCompressed) { - // Uncompress the GZIPped data: - AString Uncompressed; - if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK) + AString Metadata; + if (a_IsCompressed) { - AString HexDump; - CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); - LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); - return; + // Uncompress the GZIPped data: + if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Metadata) != Z_OK) + { + AString HexDump; + CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); + LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); + return; + } + } + else + { + Metadata = a_Metadata; } // Parse into NBT: - cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); + cParsedNBT NBT(Metadata.data(), Metadata.size()); if (!NBT.IsValid()) { AString HexDump; - CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16); - LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str()); + CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 16); + LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Metadata.size(), HexDump.c_str()); return; } @@ -2580,7 +2587,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR)) { - WriteShort(-1); + WriteChar(0); return; } @@ -2626,10 +2633,24 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); } Writer.Finish(); - AString Compressed; - CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); - WriteShort((short)Compressed.size()); - WriteBuf(Compressed.data(), Compressed.size()); + + AString Result = Writer.GetResult(); + if (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0) + { + if (Result.size() == 0) + { + WriteChar(0); + return; + } + WriteBuf(Result.data(), Result.size()); + } + else + { + AString Compressed; + CompressStringGZIP(Result.data(), Result.size(), Compressed); + WriteShort((short)Compressed.size()); + WriteBuf(Compressed.data(), Compressed.size()); + } } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 289545bc7..1e716a761 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -200,9 +200,9 @@ protected: m_Out.WriteVarUTF8String(a_Value); } - void WritePosition(const Vector3i a_Position) + void WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) { - WriteInt64(((Int64)a_Position.x & 0x3FFFFFF) << 38 | ((Int64)a_Position.y & 0xFFF) << 26 | ((Int64)a_Position.z & 0x3FFFFFF)); + m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ); } void WriteBuf(const char * a_Data, size_t a_Size) @@ -273,12 +273,12 @@ protected: // Packet handlers while in the Game state (m_State == 3): void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); - void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); - void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); - void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); + virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); void HandlePacketPlayer (cByteBuffer & a_ByteBuffer); @@ -306,10 +306,10 @@ protected: void SendCompass(const cWorld & a_World); /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ - bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ - void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); + void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata, bool a_IsCompressed = true); void StartEncryption(const Byte * a_Key); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 386e3dfb2..ffa8d5ecb 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -39,6 +39,21 @@ Implements the 1.8.x protocol classes: +#define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \ + Type Var; \ + { \ + if (!ByteBuf.Proc(Var)) \ + { \ + ByteBuf.CheckValid(); \ + return false; \ + } \ + ByteBuf.CheckValid(); \ + } + + + + + const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... class cProtocol176; @@ -59,13 +74,83 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd +void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player) +{ + // Called to spawn another player for the client + cPacketizer Pkt(*this, 0x0c); // Spawn Player packet + Pkt.WriteVarInt(a_Player.GetUniqueID()); + + // Send UUID: + AString UUID = cMojangAPI::MakeUUIDShort(a_Player.GetClientHandle()->GetUUID()); + + Int64 MostSignificantBits = 0; + Int64 LeastSignificantBits = 0; + + for (size_t i = 0; i < UUID.length(); i++) + { + MostSignificantBits += (UUID[i] & 0xff) >> 7; + LeastSignificantBits += UUID[i] & 1; + } + Pkt.WriteInt64(4053239666997989821); + Pkt.WriteInt64(-5603022497796657139); + LOG("Bits: %i, %i", (int)MostSignificantBits, (int)LeastSignificantBits); + + // Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); + + Pkt.WriteFPInt(a_Player.GetPosX()); + Pkt.WriteFPInt(a_Player.GetPosY()); + Pkt.WriteFPInt(a_Player.GetPosZ()); + Pkt.WriteByteAngle(a_Player.GetYaw()); + Pkt.WriteByteAngle(a_Player.GetPitch()); + short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; + Pkt.WriteShort(ItemType); + Pkt.WriteByte((3 << 5) | 6); // Metadata: float + index 6 + Pkt.WriteFloat((float)a_Player.GetHealth()); + Pkt.WriteByte((4 << 5 | (2 & 0x1F)) & 0xFF); + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteByte(0x7f); // Metadata: end +} + + + + + +void cProtocol180::SendPlayerMaxSpeed(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x20); // Entity Properties + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteVarInt(Player->GetUniqueID()); + Pkt.WriteInt(1); // Count + Pkt.WriteString("generic.movementSpeed"); + // The default game speed is 0.1, multiply that value by the relative speed: + Pkt.WriteDouble(0.1 * Player->GetNormalMaxSpeed()); + if (Player->IsSprinting()) + { + Pkt.WriteVarInt(1); // Modifier count + Pkt.WriteInt64(0x662a6b8dda3e4c1c); + Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier + Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); + Pkt.WriteByte(2); + } + else + { + Pkt.WriteVarInt(0); // Modifier count + } +} + + + + + void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x28); // Effect packet Pkt.WriteInt(a_EffectID); - Pkt.WritePosition(Vector3i(a_SrcX, a_SrcY, a_SrcZ)); + Pkt.WritePosition(a_SrcX, a_SrcY, a_SrcZ); Pkt.WriteInt(a_Data); Pkt.WriteBool(false); } @@ -144,7 +229,7 @@ void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc cPacketizer Pkt(*this, 0x0a); Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); } @@ -441,7 +526,7 @@ void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x23); // Block Change packet - Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15); Pkt.WriteVarInt(Block); @@ -624,8 +709,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) // Send the spawn position: { cPacketizer Pkt(*this, 0x05); // Spawn Position packet - Vector3i Position(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); - Pkt.WritePosition(Position); + Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); } // Send player abilities: @@ -636,6 +720,61 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) +{ + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); + if (ItemType == -1) + { + // The item is empty, no more data follows + a_Item.Empty(); + return true; + } + a_Item.m_ItemType = ItemType; + + HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, ItemCount); + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemDamage); + a_Item.m_ItemCount = ItemCount; + a_Item.m_ItemDamage = ItemDamage; + if (ItemCount <= 0) + { + a_Item.Empty(); + } + + HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, FirstChar); + if (FirstChar == 0) + { + // No metadata + return true; + } + a_ByteBuffer.ReverseRead(1); + + // Read the metadata + AString Metadata; + a_ByteBuffer.ReadAll(Metadata); + + ParseItemMetadata(a_Item, Metadata, false); + return true; +} + + + + + +void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); + cItem Item; + if (!ReadItem(a_ByteBuffer, Item)) + { + return; + } + m_Client->HandleCreativeInventory(SlotNum, Item); +} + + + + + void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID); @@ -672,7 +811,10 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - a_ByteBuffer.ReadAll(Data); + if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) + { + return; + } m_Client->HandlePluginMessage(Channel, Data); } @@ -940,7 +1082,7 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags); - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags); m_Client->SetLocale(Locale); @@ -950,3 +1092,43 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) + +void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) +{ + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + { + return; + } + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); + cItem Item; + ReadItem(a_ByteBuffer, Item); + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ); + m_Client->HandleRightClick(BlockX, BlockY, BlockZ, static_cast(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); +} + + + + + +void cProtocol180::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status); + + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + { + return; + } + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); + m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, static_cast(Face), Status); +} + + + + diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index d9fd5d573..dc3739369 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -54,12 +54,12 @@ public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPlayerMaxSpeed (void) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendLoginSuccess (void) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override {} virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {} - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override {} - virtual void SendWholeInventory (const cWindow & a_Window) override {} virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; virtual void SendPlayerMoveLook (void) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; @@ -92,6 +92,8 @@ public: protected: + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) override; + virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; // Packet handlers while in the Login state (m_State == 2): @@ -99,6 +101,7 @@ protected: virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override; // Packet handlers while in the Game state (m_State == 3): + virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) override; @@ -108,6 +111,8 @@ protected: virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer); } ; -- cgit v1.2.3 From fa2b69b3f36cdfa755f9c466abe49ece70303062 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 17:08:28 +0200 Subject: 1.8: Fixed tab complete. --- src/Protocol/Protocol17x.h | 2 +- src/Protocol/Protocol18x.cpp | 17 +++++++++++++++++ src/Protocol/Protocol18x.h | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 1e716a761..f056f262a 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -289,7 +289,7 @@ protected: virtual void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer); virtual void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); - void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); + virtual void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer); virtual void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index ffa8d5ecb..eebac7a05 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1132,3 +1132,20 @@ void cProtocol180::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) + +void cProtocol180::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, HasPosition); + + if (HasPosition) + { + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Position); + } + + m_Client->HandleTabCompletion(Text); +} + + + + diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index dc3739369..a3478e674 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -112,7 +112,8 @@ protected: virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer); + virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)override; + virtual void HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) override; } ; -- cgit v1.2.3 From 64071aeda9d31dfc89c3bf365d541d5968ece9da Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 8 Sep 2014 17:45:23 +0100 Subject: capitalisation error --- src/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index 8e88ba1af..870662f36 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -151,7 +151,7 @@ void cRoot::Start(void) m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init if (!m_Server->InitServer(IniFile)) { - IniFile.WriteFile("Settings.ini"); + IniFile.WriteFile("settings.ini"); LOGERROR("Failure starting server, aborting..."); return; } -- cgit v1.2.3 From e740739d0417c1c2e9693fba118b7a10e857a170 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 19:24:33 +0200 Subject: Recoded cProtocol180 class. --- src/Protocol/Protocol17x.cpp | 72 +- src/Protocol/Protocol17x.h | 43 +- src/Protocol/Protocol18x.cpp | 3205 +++++++++++++++++++++++++++++++++--------- src/Protocol/Protocol18x.h | 307 +++- 4 files changed, 2864 insertions(+), 763 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9a7111a43..0b94cb144 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1531,17 +1531,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); m_ReceivedData.CommitRead(); - // 1.8 - Compressed packets - if ((m_State == 3) && (GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)) - { - UInt32 CompressedSize; - if (!bb.ReadVarInt(CompressedSize)) - { - // Not enough data - break; - } - } - // Write one NUL extra, so that we can detect over-reads bb.Write("\0", 1); @@ -2290,7 +2279,6 @@ void cProtocol172::SendData(const char * a_Data, size_t a_Size) - bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) { HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); @@ -2332,32 +2320,25 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) -void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata, bool a_IsCompressed) +void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { - AString Metadata; - if (a_IsCompressed) + // Uncompress the GZIPped data: + AString Uncompressed; + if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK) { - // Uncompress the GZIPped data: - if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Metadata) != Z_OK) - { - AString HexDump; - CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); - LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); - return; - } - } - else - { - Metadata = a_Metadata; + AString HexDump; + CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); + LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); + return; } // Parse into NBT: - cParsedNBT NBT(Metadata.data(), Metadata.size()); + cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) { AString HexDump; - CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 16); - LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Metadata.size(), HexDump.c_str()); + CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16); + LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str()); return; } @@ -2531,15 +2512,7 @@ cProtocol172::cPacketizer::~cPacketizer() // Send the packet length UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace(); - if ((m_Protocol.m_State == 3) && (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)) - { - m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen + 1); - m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); - } - else - { - m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); - } + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); m_Protocol.SendData(DataToSend.data(), DataToSend.size()); m_Protocol.m_OutPacketLenBuffer.CommitRead(); @@ -2634,23 +2607,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) } Writer.Finish(); - AString Result = Writer.GetResult(); - if (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0) - { - if (Result.size() == 0) - { - WriteChar(0); - return; - } - WriteBuf(Result.data(), Result.size()); - } - else - { - AString Compressed; - CompressStringGZIP(Result.data(), Result.size(), Compressed); - WriteShort((short)Compressed.size()); - WriteBuf(Compressed.data(), Compressed.size()); - } + AString Compressed; + CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); + WriteShort((short)Compressed.size()); + WriteBuf(Compressed.data(), Compressed.size()); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index f056f262a..7955505f9 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -199,11 +199,6 @@ protected: { m_Out.WriteVarUTF8String(a_Value); } - - void WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) - { - m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ); - } void WriteBuf(const char * a_Data, size_t a_Size) { @@ -257,41 +252,41 @@ protected: /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ void AddReceivedData(const char * a_Data, size_t a_Size); - + /** Reads and handles the packet. The packet length and type have already been read. Returns true if the packet was understood, false if it was an unknown packet */ bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType); - + // Packet handlers while in the Status state (m_State == 1): void HandlePacketStatusPing(cByteBuffer & a_ByteBuffer); virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer); - + // Packet handlers while in the Login state (m_State == 2): - virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); - virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); + void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); + void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); // Packet handlers while in the Game state (m_State == 3): void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); - virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); + void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); + void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); + void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); + void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); + void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); void HandlePacketPlayer (cByteBuffer & a_ByteBuffer); void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer); void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); + void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); + void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); + void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer); - virtual void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); + void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); @@ -309,7 +304,7 @@ protected: virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ - void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata, bool a_IsCompressed = true); + void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); void StartEncryption(const Byte * a_Key); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index eebac7a05..1793583a2 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -9,20 +9,41 @@ Implements the 1.8.x protocol classes: */ #include "Globals.h" -#include "Bindings/PluginManager.h" #include "json/json.h" -#include "ChunkDataSerializer.h" -#include "ProtocolRecognizer.h" #include "Protocol18x.h" +#include "ProtocolRecognizer.h" +#include "ChunkDataSerializer.h" +#include "PolarSSL++/Sha1Checksum.h" #include "../ClientHandle.h" -#include "../CompositeChat.h" #include "../Root.h" #include "../Server.h" #include "../World.h" +#include "../StringCompression.h" +#include "../CompositeChat.h" +#include "../Statistics.h" -#include "../Entities/Player.h" +#include "../WorldStorage/FastNBT.h" +#include "../WorldStorage/EnchantmentSerializer.h" + +#include "../Entities/ExpOrb.h" +#include "../Entities/Minecart.h" +#include "../Entities/FallingBlock.h" #include "../Entities/Painting.h" +#include "../Entities/Pickup.h" +#include "../Entities/Player.h" +#include "../Entities/ItemFrame.h" +#include "../Entities/ArrowEntity.h" +#include "../Entities/FireworkEntity.h" + +#include "../Mobs/IncludeAllMonsters.h" +#include "../UI/Window.h" + +#include "../BlockEntities/BeaconEntity.h" +#include "../BlockEntities/CommandBlockEntity.h" +#include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" +#include "Bindings/PluginManager.h" @@ -55,88 +76,63 @@ Implements the 1.8.x protocol classes: const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... -class cProtocol176; -//////////////////////////////////////////////////////////////////////////////// -// cProtocol180: +// fwd: main.cpp: +extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; -cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client, a_ServerAddress, a_ServerPort, a_State) -{ - m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_8_0; -} +//////////////////////////////////////////////////////////////////////////////// +// cProtocol180: -void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player) +cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : + super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_8_0), + m_ServerAddress(a_ServerAddress), + m_ServerPort(a_ServerPort), + m_State(a_State), + m_ReceivedData(32 KiB), + m_OutPacketBuffer(64 KiB), + m_OutPacketLenBuffer(20), // 20 bytes is more than enough for one VarInt + m_IsEncrypted(false), + m_LastSentDimension(dimNotSet) { - // Called to spawn another player for the client - cPacketizer Pkt(*this, 0x0c); // Spawn Player packet - Pkt.WriteVarInt(a_Player.GetUniqueID()); - - // Send UUID: - AString UUID = cMojangAPI::MakeUUIDShort(a_Player.GetClientHandle()->GetUUID()); - - Int64 MostSignificantBits = 0; - Int64 LeastSignificantBits = 0; - - for (size_t i = 0; i < UUID.length(); i++) + // Create the comm log file, if so requested: + if (g_ShouldLogCommIn || g_ShouldLogCommOut) { - MostSignificantBits += (UUID[i] & 0xff) >> 7; - LeastSignificantBits += UUID[i] & 1; + static int sCounter = 0; + cFile::CreateFolder("CommLogs"); + AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(NULL), sCounter++, a_Client->GetIPString().c_str()); + m_CommLogFile.Open(FileName, cFile::fmWrite); } - Pkt.WriteInt64(4053239666997989821); - Pkt.WriteInt64(-5603022497796657139); - LOG("Bits: %i, %i", (int)MostSignificantBits, (int)LeastSignificantBits); - - // Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); - - Pkt.WriteFPInt(a_Player.GetPosX()); - Pkt.WriteFPInt(a_Player.GetPosY()); - Pkt.WriteFPInt(a_Player.GetPosZ()); - Pkt.WriteByteAngle(a_Player.GetYaw()); - Pkt.WriteByteAngle(a_Player.GetPitch()); - short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; - Pkt.WriteShort(ItemType); - Pkt.WriteByte((3 << 5) | 6); // Metadata: float + index 6 - Pkt.WriteFloat((float)a_Player.GetHealth()); - Pkt.WriteByte((4 << 5 | (2 & 0x1F)) & 0xFF); - Pkt.WriteString(a_Player.GetName()); - Pkt.WriteByte(0x7f); // Metadata: end } -void cProtocol180::SendPlayerMaxSpeed(void) +void cProtocol180::DataReceived(const char * a_Data, size_t a_Size) { - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, 0x20); // Entity Properties - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteVarInt(Player->GetUniqueID()); - Pkt.WriteInt(1); // Count - Pkt.WriteString("generic.movementSpeed"); - // The default game speed is 0.1, multiply that value by the relative speed: - Pkt.WriteDouble(0.1 * Player->GetNormalMaxSpeed()); - if (Player->IsSprinting()) + if (m_IsEncrypted) { - Pkt.WriteVarInt(1); // Modifier count - Pkt.WriteInt64(0x662a6b8dda3e4c1c); - Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier - Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); - Pkt.WriteByte(2); + Byte Decrypted[512]; + while (a_Size > 0) + { + size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; + m_Decryptor.ProcessData(Decrypted, (Byte *)a_Data, NumBytes); + AddReceivedData((const char *)Decrypted, NumBytes); + a_Size -= NumBytes; + a_Data += NumBytes; + } } else { - Pkt.WriteVarInt(0); // Modifier count + AddReceivedData(a_Data, a_Size); } } @@ -144,14 +140,13 @@ void cProtocol180::SendPlayerMaxSpeed(void) -void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) +void cProtocol180::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x28); // Effect packet - Pkt.WriteInt(a_EffectID); - Pkt.WritePosition(a_SrcX, a_SrcY, a_SrcZ); - Pkt.WriteInt(a_Data); + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteInt((a_Vehicle != NULL) ? a_Vehicle->GetUniqueID() : 0); Pkt.WriteBool(false); } @@ -159,242 +154,335 @@ void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src -void cProtocol180::SendLoginSuccess(void) +void cProtocol180::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) { - ASSERT(m_State == 2); // State: login? - - // Enable compression: - { - cPacketizer Pkt(*this, 0x03); // Set compression packet - Pkt.WriteVarInt(256); - } - - m_State = 3; // State = Game - - { - cPacketizer Pkt(*this, 0x02); // Login success packet - Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); - Pkt.WriteString(m_Client->GetUsername()); - } + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x24); // Block Action packet + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteByte(a_Byte1); + Pkt.WriteByte(a_Byte2); + Pkt.WriteVarInt(a_BlockType); } -void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocol180::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x2A); - Pkt.WriteString(a_ParticleName); - Pkt.WriteFloat(a_SrcX); - Pkt.WriteFloat(a_SrcY); - Pkt.WriteFloat(a_SrcZ); - Pkt.WriteFloat(a_OffsetX); - Pkt.WriteFloat(a_OffsetY); - Pkt.WriteFloat(a_OffsetZ); - Pkt.WriteFloat(a_ParticleData); - Pkt.WriteInt(a_ParticleAmmount);*/ + cPacketizer Pkt(*this, 0x25); // Block Break Animation packet + Pkt.WriteVarInt(a_EntityID); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteChar(a_Stage); } -void cProtocol180::SendPlayerMoveLook(void) +void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, 0x08); // Player Position And Look packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteDouble(Player->GetPosX()); - - // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. - Pkt.WriteDouble(Player->GetStance() + 0.001); - - Pkt.WriteDouble(Player->GetPosZ()); - Pkt.WriteFloat((float)Player->GetYaw()); - Pkt.WriteFloat((float)Player->GetPitch()); - Pkt.WriteByte(0); + + cPacketizer Pkt(*this, 0x23); // Block Change packet + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteVarInt(((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15)); } -void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) +void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, 0x0a); - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + + /*cPacketizer Pkt(*this, 0x22); // Multi Block Change packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteVarInt((UInt32)a_Changes.size()); + for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) + { + short Coords = itr->y | (itr->z << 8) | (itr->x << 12); + Pkt.WriteShort(Coords); + + UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15); + Pkt.WriteVarInt(Block); + } // for itr - a_Changes[]*/ } -void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) +void cProtocol180::SendChat(const AString & a_Message) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0d); // Collect Item packet - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteVarInt(a_Player.GetUniqueID()); + cPacketizer Pkt(*this, 0x02); // Chat Message packet + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); + Pkt.WriteChar(0); } -void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) +void cProtocol180::SendChat(const cCompositeChat & a_Message) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x12); // Entity Velocity packet - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick - Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); - Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); - Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); -} + // Compose the complete Json string to send: + Json::Value msg; + cWorld * World = m_Client->GetPlayer()->GetWorld(); + msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present + const cCompositeChat::cParts & Parts = a_Message.GetParts(); + for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) + { + Json::Value Part; + switch ((*itr)->m_PartType) + { + case cCompositeChat::ptText: + { + Part["text"] = (*itr)->m_Text; + AddChatPartStyle(Part, (*itr)->m_Style); + break; + } + + case cCompositeChat::ptClientTranslated: + { + const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; + Part["translate"] = p.m_Text; + Json::Value With; + for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) + { + With.append(*itrW); + } + if (!p.m_Parameters.empty()) + { + Part["with"] = With; + } + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptUrl: + { + const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Url; + Url["action"] = "open_url"; + Url["value"] = p.m_Url; + Part["clickEvent"] = Url; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptSuggestCommand: + case cCompositeChat::ptRunCommand: + { + const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Cmd; + Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; + Cmd["value"] = p.m_Command; + Part["clickEvent"] = Cmd; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptShowAchievement: + { + const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; + Part["translate"] = "chat.type.achievement"; + Json::Value Ach; + Ach["action"] = "show_achievement"; + Ach["value"] = p.m_Text; + + Json::Value AchColourAndName; + AchColourAndName["color"] = "green"; + AchColourAndName["translate"] = p.m_Text; + AchColourAndName["hoverEvent"] = Ach; + Json::Value Extra; + Extra.append(AchColourAndName); + Json::Value Name; + Name["text"] = p.m_PlayerName; + Json::Value With; + With.append(Name); + With.append(Extra); -void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) -{ - ASSERT(m_State == 3); // In game mode? + Part["with"] = With; + AddChatPartStyle(Part, p.m_Style); + break; + } + } + msg["extra"].append(Part); + } // for itr - Parts[] - /*cPacketizer Pkt(*this, 0x13); // Destroy Entities packet - Pkt.WriteVarInt(1); - Pkt.WriteVarInt(a_Entity.GetUniqueID());*/ + // Send the message to the client: + cPacketizer Pkt(*this, 0x02); + Pkt.WriteString(msg.toStyledString()); + Pkt.WriteChar(0); } -void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteByte(a_RelX); - Pkt.WriteByte(a_RelY); - Pkt.WriteByte(a_RelZ); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + + // Serialize first, before creating the Packetizer (the packetizer locks a CS) + // This contains the flags and bitmasks, too + const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ); + + cCSLock Lock(m_CSPacket); + SendData(ChunkData.data(), ChunkData.size()); } -void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + cPacketizer Pkt(*this, 0x0d); // Collect Item packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteByte(a_RelX); - Pkt.WriteByte(a_RelY); - Pkt.WriteByte(a_RelZ); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + Pkt.WriteVarInt(a_Player.GetUniqueID()); } -void cProtocol180::SendEntityLook(const cEntity & a_Entity) +void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x16); // Entity Look packet - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + /*cPacketizer Pkt(*this, 0x13); // Destroy Entities packet + Pkt.WriteVarInt(1); + Pkt.WriteVarInt(a_Entity.GetUniqueID());*/ } -void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) +void cProtocol180::SendDisconnect(const AString & a_Reason) +{ + switch (m_State) + { + case 2: + { + // During login: + cPacketizer Pkt(*this, 0); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); + break; + } + case 3: + { + // In-game: + cPacketizer Pkt(*this, 0x40); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Reason).c_str())); + break; + } + } +} + + + + + +void cProtocol180::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x18); + cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet + Pkt.WriteInt(a_BlockX); + Pkt.WriteInt(a_BlockY); + Pkt.WriteInt(a_BlockZ); +} + + + + + +void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteFPInt(a_Entity.GetPosX()); - Pkt.WriteFPInt(a_Entity.GetPosY()); - Pkt.WriteFPInt(a_Entity.GetPosZ()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGrond() on entities*/ + Pkt.WriteByte(a_EffectID); + Pkt.WriteByte(a_Amplifier); + Pkt.WriteVarInt((UInt32)a_Duration); + Pkt.WriteBool(false); // Hide particles } -void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) +void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + /*cPacketizer Pkt(*this, 0x04); // Entity Equipment packet Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetHeadYaw());*/ + Pkt.WriteShort(a_SlotNum); + Pkt.WriteItem(a_Item);*/ } -void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) +void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteEntityMetadata(a_Entity); - Pkt.WriteByte(0x7f); // The termination byte*/ + /*cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); + Pkt.WriteByteAngle(a_Entity.GetHeadYaw());*/ } -void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +void cProtocol180::SendEntityLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1D); // Entity Effect packet + /*cPacketizer Pkt(*this, 0x16); // Entity Look packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteByte(a_EffectID); - Pkt.WriteByte(a_Amplifier); - Pkt.WriteVarInt((UInt32)a_Duration); - Pkt.WriteBool(false); // Hide particles + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } -void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1e); + /*cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteByte(a_EffectID); + Pkt.WriteEntityMetadata(a_Entity); + Pkt.WriteByte(0x7f); // The termination byte*/ } @@ -414,306 +502,1823 @@ void cProtocol180::SendEntityProperties(const cEntity & a_Entity) -void cProtocol180::SendKeepAlive(int a_PingID) +void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { - // Drop the packet if the protocol is not in the Game state yet (caused a client crash): - if (m_State != 3) - { - LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); - return; - } + ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x00); // Keep Alive packet - Pkt.WriteVarInt(a_PingID); + /*cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_RelX); + Pkt.WriteByte(a_RelY); + Pkt.WriteByte(a_RelZ); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } -void cProtocol180::SendHealth(void) +void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, 0x06); // Update Health packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteFloat((float)Player->GetHealth()); - Pkt.WriteVarInt((UInt32)Player->GetFoodLevel()); - Pkt.WriteFloat((float)Player->GetFoodSaturationLevel()); + + /*cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_RelX); + Pkt.WriteByte(a_RelY); + Pkt.WriteByte(a_RelZ); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ } -void cProtocol180::SendExperience(void) +void cProtocol180::SendEntityStatus(const cEntity & a_Entity, char a_Status) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x1f); // Experience Packet - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteFloat(Player->GetXpPercentage()); - Pkt.WriteVarInt((UInt32)Player->GetXpLevel()); - Pkt.WriteVarInt((UInt32)Player->GetCurrentXp()); + cPacketizer Pkt(*this, 0x1a); // Entity Status packet + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteChar(a_Status); } -void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) +void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x10); // Spawn Painting packet - Pkt.WriteVarInt(a_Painting.GetUniqueID()); - Pkt.WriteString(a_Painting.GetName().c_str()); - Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ())); - Pkt.WriteChar(a_Painting.GetDirection());*/ + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick + Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); } -void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & a_Message) +void cProtocol180::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x3f); - Pkt.WriteString(a_Channel); - Pkt.WriteBuf(a_Message.data(), a_Message.size()); + cPacketizer Pkt(*this, 0x27); // Explosion packet + Pkt.WriteFloat((float)a_BlockX); + Pkt.WriteFloat((float)a_BlockY); + Pkt.WriteFloat((float)a_BlockZ); + Pkt.WriteFloat((float)a_Radius); + Pkt.WriteInt((int)a_BlocksAffected.size()); + for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(), end = a_BlocksAffected.end(); itr != end; ++itr) + { + Pkt.WriteChar((char)itr->x); + Pkt.WriteChar((char)itr->y); + Pkt.WriteChar((char)itr->z); + } // for itr - a_BlockAffected[] + Pkt.WriteFloat((float)a_PlayerMotion.x); + Pkt.WriteFloat((float)a_PlayerMotion.y); + Pkt.WriteFloat((float)a_PlayerMotion.z); } -void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +void cProtocol180::SendGameMode(eGameMode a_GameMode) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x21); // Chunk Data packet - Pkt.WriteInt(a_ChunkX); - Pkt.WriteInt(a_ChunkZ); - Pkt.WriteBool(true); - Pkt.WriteShort(0); // Primary bitmap - Pkt.WriteVarInt(0); // Data size + cPacketizer Pkt(*this, 0x2b); // Change Game State packet + Pkt.WriteByte(3); // Reason: Change game mode + Pkt.WriteFloat((float)a_GameMode); } -void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) +void cProtocol180::SendHealth(void) { ASSERT(m_State == 3); // In game mode? - // Serialize first, before creating the Packetizer (the packetizer locks a CS) - // This contains the flags and bitmasks, too - const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ); - - cCSLock Lock(m_CSPacket); - SendData(ChunkData.data(), ChunkData.size()); + cPacketizer Pkt(*this, 0x06); // Update Health packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteFloat((float)Player->GetHealth()); + Pkt.WriteVarInt((UInt32)Player->GetFoodLevel()); + Pkt.WriteFloat((float)Player->GetFoodSaturationLevel()); } -void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +void cProtocol180::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x23); // Block Change packet - Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); - - UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15); - Pkt.WriteVarInt(Block); + cPacketizer Pkt(*this, 0x2f); // Set Slot packet + Pkt.WriteChar(a_WindowID); + Pkt.WriteShort(a_SlotNum); + Pkt.WriteItem(a_Item); } -void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) +void cProtocol180::SendKeepAlive(int a_PingID) { - ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x22); // Multi Block Change packet - Pkt.WriteInt(a_ChunkX); - Pkt.WriteInt(a_ChunkZ); - Pkt.WriteVarInt((UInt32)a_Changes.size()); - for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) + // Drop the packet if the protocol is not in the Game state yet (caused a client crash): + if (m_State != 3) { - short Coords = itr->y | (itr->z << 8) | (itr->x << 12); - Pkt.WriteShort(Coords); - - UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15); - Pkt.WriteVarInt(Block); - } // for itr - a_Changes[]*/ + LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); + return; + } + + cPacketizer Pkt(*this, 0x00); // Keep Alive packet + Pkt.WriteVarInt(a_PingID); } -void cProtocol180::SendChat(const AString & a_Message) +void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) { - ASSERT(m_State == 3); // In game mode? + // Send the Join Game packet: + { + cServer * Server = cRoot::Get()->GetServer(); + cPacketizer Pkt(*this, 0x01); // Join Game packet + Pkt.WriteInt(a_Player.GetUniqueID()); + Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 + Pkt.WriteChar((char)a_World.GetDimension()); + Pkt.WriteByte(2); // TODO: Difficulty (set to Normal) + Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60)); + Pkt.WriteString("default"); // Level type - wtf? + Pkt.WriteBool(false); // Reduced Debug Info - wtf? + } + m_LastSentDimension = a_World.GetDimension(); - cPacketizer Pkt(*this, 0x02); // Chat Message packet - Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); - Pkt.WriteChar(0); + // Send the spawn position: + { + cPacketizer Pkt(*this, 0x05); // Spawn Position packet + Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); + } + + // Send player abilities: + SendPlayerAbilities(); } - -void cProtocol180::SendChat(const cCompositeChat & a_Message) +void cProtocol180::SendLoginSuccess(void) { - ASSERT(m_State == 3); // In game mode? + ASSERT(m_State == 2); // State: login? - // Compose the complete Json string to send: - Json::Value msg; - cWorld * World = m_Client->GetPlayer()->GetWorld(); - msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present - const cCompositeChat::cParts & Parts = a_Message.GetParts(); - for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) + // Enable compression: { - Json::Value Part; - switch ((*itr)->m_PartType) - { - case cCompositeChat::ptText: - { - Part["text"] = (*itr)->m_Text; - AddChatPartStyle(Part, (*itr)->m_Style); - break; - } - - case cCompositeChat::ptClientTranslated: + cPacketizer Pkt(*this, 0x03); // Set compression packet + Pkt.WriteVarInt(256); + } + + m_State = 3; // State = Game + + { + cPacketizer Pkt(*this, 0x02); // Login success packet + Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); + Pkt.WriteString(m_Client->GetUsername()); + } +} + + + + + +void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x10); // Spawn Painting packet + Pkt.WriteVarInt(a_Painting.GetUniqueID()); + Pkt.WriteString(a_Painting.GetName().c_str()); + Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ())); + Pkt.WriteChar(a_Painting.GetDirection());*/ +} + + + + + +void cProtocol180::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x34); + Pkt.WriteVarInt(a_ID); + Pkt.WriteShort (3 + a_Length); + + Pkt.WriteByte(0); + Pkt.WriteByte(a_X); + Pkt.WriteByte(a_Y); + + for (unsigned int i = 0; i < a_Length; ++i) + { + Pkt.WriteByte(a_Colors[i]); + } +} + + + + + +void cProtocol180::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x34); + Pkt.WriteVarInt(a_ID); + Pkt.WriteShort ((short)(1 + (3 * a_Decorators.size()))); + + Pkt.WriteByte(1); + + for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it) + { + Pkt.WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf)); + Pkt.WriteByte(it->GetPixelX()); + Pkt.WriteByte(it->GetPixelZ()); + } +} + + + + + +void cProtocol180::SendMapInfo(int a_ID, unsigned int a_Scale) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x34); + Pkt.WriteVarInt(a_ID); + Pkt.WriteShort (2); + + Pkt.WriteByte(2); + Pkt.WriteByte(a_Scale); +} + + + + + + +void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) +{ + ASSERT(m_State == 3); // In game mode? + + /*{ + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet + Pkt.WriteVarInt(a_Pickup.GetUniqueID()); + Pkt.WriteByte(2); // Type = Pickup + Pkt.WriteFPInt(a_Pickup.GetPosX()); + Pkt.WriteFPInt(a_Pickup.GetPosY()); + Pkt.WriteFPInt(a_Pickup.GetPosZ()); + Pkt.WriteByteAngle(a_Pickup.GetYaw()); + Pkt.WriteByteAngle(a_Pickup.GetPitch()); + Pkt.WriteInt(0); // No object data + } + + { + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + Pkt.WriteVarInt(a_Pickup.GetUniqueID()); + Pkt.WriteByte((0x05 << 5) | 10); // Slot type + index 10 + Pkt.WriteItem(a_Pickup.GetItem()); + Pkt.WriteByte(0x7f); // End of metadata + }*/ +} + + + + + +void cProtocol180::SendPlayerAbilities(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x39); // Player Abilities packet + Byte Flags = 0; + cPlayer * Player = m_Client->GetPlayer(); + if (Player->IsGameModeCreative()) + { + Flags |= 0x01; + Flags |= 0x08; // Godmode, used for creative + } + if (Player->IsFlying()) + { + Flags |= 0x02; + } + if (Player->CanFly()) + { + Flags |= 0x04; + } + Pkt.WriteByte(Flags); + Pkt.WriteFloat((float)(0.05 * Player->GetFlyingMaxSpeed())); + Pkt.WriteFloat((float)(0.1 * Player->GetNormalMaxSpeed())); +} + + + + + +void cProtocol180::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0b); // Animation packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteChar(a_Animation); +} + + + + + +void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x2A); + Pkt.WriteString(a_ParticleName); + Pkt.WriteFloat(a_SrcX); + Pkt.WriteFloat(a_SrcY); + Pkt.WriteFloat(a_SrcZ); + Pkt.WriteFloat(a_OffsetX); + Pkt.WriteFloat(a_OffsetY); + Pkt.WriteFloat(a_OffsetZ); + Pkt.WriteFloat(a_ParticleData); + Pkt.WriteInt(a_ParticleAmmount);*/ +} + + + + + +void cProtocol180::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteBool(a_IsOnline); + Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0);*/ +} + + + + + +void cProtocol180::SendPlayerMaxSpeed(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x20); // Entity Properties + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteVarInt(Player->GetUniqueID()); + Pkt.WriteInt(1); // Count + Pkt.WriteString("generic.movementSpeed"); + // The default game speed is 0.1, multiply that value by the relative speed: + Pkt.WriteDouble(0.1 * Player->GetNormalMaxSpeed()); + if (Player->IsSprinting()) + { + Pkt.WriteVarInt(1); // Modifier count + Pkt.WriteInt64(0x662a6b8dda3e4c1c); + Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier + Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); + Pkt.WriteByte(2); + } + else + { + Pkt.WriteVarInt(0); // Modifier count + } +} + + + + + +void cProtocol180::SendPlayerMoveLook(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteDouble(Player->GetPosX()); + + // The "+ 0.001" is there because otherwise the player falls through the block they were standing on. + Pkt.WriteDouble(Player->GetStance() + 0.001); + + Pkt.WriteDouble(Player->GetPosZ()); + Pkt.WriteFloat((float)Player->GetYaw()); + Pkt.WriteFloat((float)Player->GetPitch()); + Pkt.WriteByte(0); +} + + + + + +void cProtocol180::SendPlayerPosition(void) +{ + // There is no dedicated packet for this, send the whole thing: + SendPlayerMoveLook(); +} + + + + + +void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player) +{ + // Called to spawn another player for the client + cPacketizer Pkt(*this, 0x0c); // Spawn Player packet + Pkt.WriteVarInt(a_Player.GetUniqueID()); + + // Fake UUID + Pkt.WriteInt64(4053239666997989821); + Pkt.WriteInt64(-5603022497796657139); + + Pkt.WriteFPInt(a_Player.GetPosX()); + Pkt.WriteFPInt(a_Player.GetPosY()); + Pkt.WriteFPInt(a_Player.GetPosZ()); + Pkt.WriteByteAngle(a_Player.GetYaw()); + Pkt.WriteByteAngle(a_Player.GetPitch()); + short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; + Pkt.WriteShort(ItemType); + Pkt.WriteByte((3 << 5) | 6); // Metadata: float + index 6 + Pkt.WriteFloat((float)a_Player.GetHealth()); + Pkt.WriteByte((4 << 5 | (2 & 0x1F)) & 0xFF); + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteByte(0x7f); // Metadata: end +} + + + + + +void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & a_Message) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3f); + Pkt.WriteString(a_Channel); + Pkt.WriteBuf(a_Message.data(), a_Message.size()); +} + + + + + +void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1e); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_EffectID); +} + + + + + +void cProtocol180::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) +{ + if ((m_LastSentDimension == a_Dimension) && !a_ShouldIgnoreDimensionChecks) + { + // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death) + return; + } + + cPacketizer Pkt(*this, 0x07); // Respawn packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteInt((int)a_Dimension); + Pkt.WriteByte(2); // TODO: Difficulty (set to Normal) + Pkt.WriteByte((Byte)Player->GetEffectiveGameMode()); + Pkt.WriteString("default"); + m_LastSentDimension = a_Dimension; +} + + + + + +void cProtocol180::SendExperience(void) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x1f); // Experience Packet + cPlayer * Player = m_Client->GetPlayer(); + Pkt.WriteFloat(Player->GetXpPercentage()); + Pkt.WriteVarInt((UInt32)Player->GetXpLevel()); + Pkt.WriteVarInt((UInt32)Player->GetCurrentXp()); +} + + + + + +void cProtocol180::SendExperienceOrb(const cExpOrb & a_ExpOrb) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x11); + Pkt.WriteVarInt(a_ExpOrb.GetUniqueID()); + Pkt.WriteFPInt(a_ExpOrb.GetPosX()); + Pkt.WriteFPInt(a_ExpOrb.GetPosY()); + Pkt.WriteFPInt(a_ExpOrb.GetPosZ()); + Pkt.WriteShort(a_ExpOrb.GetReward()); +} + + + + + +void cProtocol180::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3b); + Pkt.WriteString(a_Name); + Pkt.WriteString(a_DisplayName); + Pkt.WriteByte(a_Mode); +} + + + + + +void cProtocol180::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3c); + Pkt.WriteString(a_Player); + Pkt.WriteByte(a_Mode); + + if (a_Mode != 1) + { + Pkt.WriteString(a_Objective); + Pkt.WriteInt((int) a_Score); + } +} + + + + + +void cProtocol180::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3d); + Pkt.WriteByte((int) a_Display); + Pkt.WriteString(a_Objective); +} + + + + + +void cProtocol180::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x29); // Sound Effect packet + Pkt.WriteString(a_SoundName); + Pkt.WriteInt((int)(a_X * 8.0)); + Pkt.WriteInt((int)(a_Y * 8.0)); + Pkt.WriteInt((int)(a_Z * 8.0)); + Pkt.WriteFloat(a_Volume); + Pkt.WriteByte((Byte)(a_Pitch * 63)); +} + + + + + +void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x28); // Effect packet + Pkt.WriteInt(a_EffectID); + Pkt.WritePosition(a_SrcX, a_SrcY, a_SrcZ); + Pkt.WriteInt(a_Data); + Pkt.WriteBool(false); +} + + + + + +void cProtocol180::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet + Pkt.WriteVarInt(a_FallingBlock.GetUniqueID()); + Pkt.WriteByte(70); // Falling block + Pkt.WriteFPInt(a_FallingBlock.GetPosX()); + Pkt.WriteFPInt(a_FallingBlock.GetPosY()); + Pkt.WriteFPInt(a_FallingBlock.GetPosZ()); + Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); + Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); + Pkt.WriteInt(((int)a_FallingBlock.GetBlockType()) | (((int)a_FallingBlock.GetBlockMeta()) << 16)); // Or 0x10 + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_FallingBlock.GetSpeedZ() * 400)); +} + + + + + +void cProtocol180::SendSpawnMob(const cMonster & a_Mob) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet + Pkt.WriteVarInt(a_Mob.GetUniqueID()); + Pkt.WriteByte((Byte)a_Mob.GetMobType()); + Pkt.WriteFPInt(a_Mob.GetPosX()); + Pkt.WriteFPInt(a_Mob.GetPosY()); + Pkt.WriteFPInt(a_Mob.GetPosZ()); + Pkt.WriteByteAngle(a_Mob.GetPitch()); + Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); + Pkt.WriteByteAngle(a_Mob.GetYaw()); + Pkt.WriteShort((short)(a_Mob.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Mob.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Mob.GetSpeedZ() * 400)); + Pkt.WriteEntityMetadata(a_Mob); + Pkt.WriteByte(0x7f); // Metadata terminator +} + + + + + +void cProtocol180::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_ObjectType); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteInt(a_ObjectData); + if (a_ObjectData != 0) + { + Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); + }*/ +} + + + + + +void cProtocol180::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0xe); // Spawn Object packet + Pkt.WriteVarInt(a_Vehicle.GetUniqueID()); + Pkt.WriteByte(a_VehicleType); + Pkt.WriteFPInt(a_Vehicle.GetPosX()); + Pkt.WriteFPInt(a_Vehicle.GetPosY()); + Pkt.WriteFPInt(a_Vehicle.GetPosZ()); + Pkt.WriteByteAngle(a_Vehicle.GetPitch()); + Pkt.WriteByteAngle(a_Vehicle.GetYaw()); + Pkt.WriteInt(a_VehicleSubType); + if (a_VehicleSubType != 0) + { + Pkt.WriteShort((short)(a_Vehicle.GetSpeedX() * 400)); + Pkt.WriteShort((short)(a_Vehicle.GetSpeedY() * 400)); + Pkt.WriteShort((short)(a_Vehicle.GetSpeedZ() * 400)); + } +} + + + + + +void cProtocol180::SendStatistics(const cStatManager & a_Manager) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x37); + Pkt.WriteVarInt(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only + + for (size_t i = 0; i < (size_t)statCount; ++i) + { + StatValue Value = a_Manager.GetValue((eStatistic) i); + const AString & StatName = cStatInfo::GetName((eStatistic) i); + + Pkt.WriteString(StatName); + Pkt.WriteVarInt(Value); + } +} + + + + + +void cProtocol180::SendTabCompletionResults(const AStringVector & a_Results) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet + Pkt.WriteVarInt((int)a_Results.size()); + + for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr) + { + Pkt.WriteString(*itr); + } +} + + + + + +void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) +{ + ASSERT(m_State == 3); // In game mode? + + /*cPacketizer Pkt(*this, 0x18); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(a_Entity.GetPosY()); + Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(a_Entity.GetPitch()); + Pkt.WriteBool(true); // TODO: IsOnGrond() on entities*/ +} + + + + + +void cProtocol180::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet + Pkt.WriteVarInt(0); // EntityID = 0, always + Pkt.WriteByte(1); // Type = Thunderbolt + Pkt.WriteFPInt(a_BlockX); + Pkt.WriteFPInt(a_BlockY); + Pkt.WriteFPInt(a_BlockZ); +} + + + + + +void cProtocol180::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) +{ + ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } + + cPacketizer Pkt(*this, 0x03); + Pkt.WriteInt64(a_WorldAge); + Pkt.WriteInt64(a_TimeOfDay); +} + + + + + +void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x21); // Chunk Data packet + Pkt.WriteInt(a_ChunkX); + Pkt.WriteInt(a_ChunkZ); + Pkt.WriteBool(true); + Pkt.WriteShort(0); // Primary bitmap + Pkt.WriteVarInt(0); // Data size +} + + + + +void cProtocol180::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x35); // Update tile entity packet + Pkt.WriteInt(a_BlockEntity.GetPosX()); + Pkt.WriteShort(a_BlockEntity.GetPosY()); + Pkt.WriteInt(a_BlockEntity.GetPosZ()); + + Byte Action = 0; + switch (a_BlockEntity.GetBlockType()) + { + case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing + case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text + case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity + case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity + case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot + default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; + } + Pkt.WriteByte(Action); + + Pkt.WriteBlockEntity(a_BlockEntity); +} + + + + + +void cProtocol180::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x33); + Pkt.WriteInt(a_BlockX); + Pkt.WriteShort((short)a_BlockY); + Pkt.WriteInt(a_BlockZ); + // Need to send only up to 15 chars, otherwise the client crashes (#598) + Pkt.WriteString(a_Line1.substr(0, 15)); + Pkt.WriteString(a_Line2.substr(0, 15)); + Pkt.WriteString(a_Line3.substr(0, 15)); + Pkt.WriteString(a_Line4.substr(0, 15)); +} + + + + + +void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x0a); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +void cProtocol180::SendWeather(eWeather a_Weather) +{ + ASSERT(m_State == 3); // In game mode? + + { + cPacketizer Pkt(*this, 0x2b); // Change Game State packet + Pkt.WriteByte((a_Weather == wSunny) ? 1 : 2); // End rain / begin rain + Pkt.WriteFloat(0); // Unused for weather + } + + // TODO: Fade effect, somehow +} + + + + + +void cProtocol180::SendWholeInventory(const cWindow & a_Window) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x30); // Window Items packet + Pkt.WriteChar(a_Window.GetWindowID()); + Pkt.WriteShort(a_Window.GetNumSlots()); + cItems Slots; + a_Window.GetSlots(*(m_Client->GetPlayer()), Slots); + for (cItems::const_iterator itr = Slots.begin(), end = Slots.end(); itr != end; ++itr) + { + Pkt.WriteItem(*itr); + } // for itr - Slots[] +} + + + + + +void cProtocol180::SendWindowClose(const cWindow & a_Window) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x2e); + Pkt.WriteChar(a_Window.GetWindowID()); +} + + + + + +void cProtocol180::SendWindowOpen(const cWindow & a_Window) +{ + ASSERT(m_State == 3); // In game mode? + + if (a_Window.GetWindowType() < 0) + { + // Do not send this packet for player inventory windows + return; + } + + cPacketizer Pkt(*this, 0x2d); + Pkt.WriteChar(a_Window.GetWindowID()); + Pkt.WriteChar(a_Window.GetWindowType()); + Pkt.WriteString(a_Window.GetWindowTitle()); + Pkt.WriteChar(a_Window.GetNumNonInventorySlots()); + Pkt.WriteBool(true); + if (a_Window.GetWindowType() == cWindow::wtAnimalChest) + { + Pkt.WriteInt(0); // TODO: The animal's EntityID + } +} + + + + + +void cProtocol180::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x31); // Window Property packet + Pkt.WriteChar(a_Window.GetWindowID()); + Pkt.WriteShort(a_Property); + Pkt.WriteShort(a_Value); +} + + + + + +void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) +{ + // Write the incoming data into the comm log file: + if (g_ShouldLogCommIn) + { + if (m_ReceivedData.GetReadableSpace() > 0) + { + AString AllData; + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadAll(AllData); + m_ReceivedData.ResetRead(); + m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); + ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); + AString Hex; + CreateHexDump(Hex, AllData.data(), AllData.size(), 16); + m_CommLogFile.Printf("Incoming data, " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") unparsed bytes already present in buffer:\n%s\n", + AllData.size(), AllData.size(), Hex.c_str() + ); + } + AString Hex; + CreateHexDump(Hex, a_Data, a_Size, 16); + m_CommLogFile.Printf("Incoming data: %d (0x%x) bytes: \n%s\n", + (unsigned)a_Size, (unsigned)a_Size, Hex.c_str() + ); + m_CommLogFile.Flush(); + } + + if (!m_ReceivedData.Write(a_Data, a_Size)) + { + // Too much data in the incoming queue, report to caller: + m_Client->PacketBufferFull(); + return; + } + + // Handle all complete packets: + for (;;) + { + UInt32 PacketLen; + if (!m_ReceivedData.ReadVarInt(PacketLen)) + { + // Not enough data + m_ReceivedData.ResetRead(); + break; + } + if (!m_ReceivedData.CanReadBytes(PacketLen)) + { + // The full packet hasn't been received yet + m_ReceivedData.ResetRead(); + break; + } + cByteBuffer bb(PacketLen + 1); + VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); + m_ReceivedData.CommitRead(); + + // Compressed packets + if (m_State == 3) + { + UInt32 CompressedSize; + if (!bb.ReadVarInt(CompressedSize)) { - const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; - Part["translate"] = p.m_Text; - Json::Value With; - for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) - { - With.append(*itrW); - } - if (!p.m_Parameters.empty()) - { - Part["with"] = With; - } - AddChatPartStyle(Part, p.m_Style); + // Not enough data break; } + } + + // Write one NUL extra, so that we can detect over-reads + bb.Write("\0", 1); + + UInt32 PacketType; + if (!bb.ReadVarInt(PacketType)) + { + // Not enough data + break; + } + + // Log the packet info into the comm log file: + if (g_ShouldLogCommIn) + { + AString PacketData; + bb.ReadAll(PacketData); + bb.ResetRead(); + bb.ReadVarInt(PacketType); + ASSERT(PacketData.size() > 0); + PacketData.resize(PacketData.size() - 1); + AString PacketDataHex; + CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); + m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n", + PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() + ); + } + + if (!HandlePacket(bb, PacketType)) + { + // Unknown packet, already been reported, but without the length. Log the length here: + LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, PacketLen); - case cCompositeChat::ptUrl: + #ifdef _DEBUG + // Dump the packet contents into the log: + bb.ResetRead(); + AString Packet; + bb.ReadAll(Packet); + Packet.resize(Packet.size() - 1); // Drop the final NUL pushed there for over-read detection + AString Out; + CreateHexDump(Out, Packet.data(), (int)Packet.size(), 24); + LOGD("Packet contents:\n%s", Out.c_str()); + #endif // _DEBUG + + // Put a message in the comm log: + if (g_ShouldLogCommIn) { - const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Url; - Url["action"] = "open_url"; - Url["value"] = p.m_Url; - Part["clickEvent"] = Url; - AddChatPartStyle(Part, p.m_Style); - break; + m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); } - case cCompositeChat::ptSuggestCommand: - case cCompositeChat::ptRunCommand: + return; + } + + if (bb.GetReadableSpace() != 1) + { + // Read more or less than packet length, report as error + LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", + PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen + ); + + // Put a message in the comm log: + if (g_ShouldLogCommIn) { - const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Cmd; - Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; - Cmd["value"] = p.m_Command; - Part["clickEvent"] = Cmd; - AddChatPartStyle(Part, p.m_Style); - break; + m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got " SIZE_T_FMT " left) ^^^^^^\n\n\n", + 1, bb.GetReadableSpace() + ); + m_CommLogFile.Flush(); + } + + ASSERT(!"Read wrong number of bytes!"); + m_Client->PacketError(PacketType); + } + } // for (ever) + + // Log any leftover bytes into the logfile: + if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0)) + { + AString AllData; + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadAll(AllData); + m_ReceivedData.ResetRead(); + m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); + ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); + AString Hex; + CreateHexDump(Hex, AllData.data(), AllData.size(), 16); + m_CommLogFile.Printf("There are " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") bytes of non-parse-able data left in the buffer:\n%s", + m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() + ); + m_CommLogFile.Flush(); + } +} + + + + +bool cProtocol180::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) +{ + switch (m_State) + { + case 1: + { + // Status + switch (a_PacketType) + { + case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return true; + case 0x01: HandlePacketStatusPing (a_ByteBuffer); return true; + } + break; + } + + case 2: + { + // Login + switch (a_PacketType) + { + case 0x00: HandlePacketLoginStart (a_ByteBuffer); return true; + case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return true; + } + break; + } + + case 3: + { + // Game + switch (a_PacketType) + { + case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return true; + case 0x01: HandlePacketChatMessage (a_ByteBuffer); return true; + case 0x02: HandlePacketUseEntity (a_ByteBuffer); return true; + case 0x03: HandlePacketPlayer (a_ByteBuffer); return true; + case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return true; + case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return true; + case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return true; + case 0x07: HandlePacketBlockDig (a_ByteBuffer); return true; + case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return true; + case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return true; + case 0x0a: HandlePacketAnimation (a_ByteBuffer); return true; + case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return true; + case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return true; + case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return true; + case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true; + case 0x0f: // Confirm transaction - not used in MCS + case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true; + case 0x11: HandlePacketEnchantItem (a_ByteBuffer); return true; + case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true; + case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true; + case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true; + case 0x15: HandlePacketClientSettings (a_ByteBuffer); return true; + case 0x16: HandlePacketClientStatus (a_ByteBuffer); return true; + case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return true; } + break; + } + default: + { + // Received a packet in an unknown state, report: + LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); + + // Cannot kick the client - we don't know this state and thus the packet number for the kick packet + + // Switch to a state when all further packets are silently ignored: + m_State = 255; + return false; + } + case 255: + { + // This is the state used for "not processing packets anymore" when we receive a bad packet from a client. + // Do not output anything (the caller will do that for us), just return failure + return false; + } + } // switch (m_State) + + // Unknown packet type, report to the ClientHandle: + m_Client->PacketUnknown(a_PacketType); + return false; +} + + + + + +void cProtocol180::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp); + + cPacketizer Pkt(*this, 0x01); // Ping packet + Pkt.WriteInt64(Timestamp); +} + + + + + +void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +{ + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "1.8"; + Version["protocol"] = 47; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = ServerDescription.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + Json::StyledWriter Writer; + AString Response = Writer.write(ResponseValue); + + cPacketizer Pkt(*this, 0x00); // Response packet + Pkt.WriteString(Response); +} + + + + + +void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) +{ + UInt32 EncKeyLength, EncNonceLength; + a_ByteBuffer.ReadVarInt(EncKeyLength); + AString EncKey; + if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) + { + return; + } + a_ByteBuffer.ReadVarInt(EncNonceLength); + AString EncNonce; + if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) + { + return; + } + if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) + { + LOGD("Too long encryption"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt EncNonce using privkey + cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); + Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; + int res = rsaDecryptor.Decrypt((const Byte *)EncNonce.data(), EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); + if (res != 4) + { + LOGD("Bad nonce length: got %d, exp %d", res, 4); + m_Client->Kick("Hacked client"); + return; + } + if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) + { + LOGD("Bad nonce value"); + m_Client->Kick("Hacked client"); + return; + } + + // Decrypt the symmetric encryption key using privkey: + Byte DecryptedKey[MAX_ENC_LEN]; + res = rsaDecryptor.Decrypt((const Byte *)EncKey.data(), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); + if (res != 16) + { + LOGD("Bad key length"); + m_Client->Kick("Hacked client"); + return; + } + + StartEncryption(DecryptedKey); + m_Client->HandleLogin(4, m_Client->GetUsername()); +} + + + + + +void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) +{ + AString Username; + if (!a_ByteBuffer.ReadVarUTF8String(Username)) + { + m_Client->Kick("Bad username"); + return; + } + + if (!m_Client->HandleHandshake(Username)) + { + // The client is not welcome here, they have been sent a Kick packet already + return; + } + + cServer * Server = cRoot::Get()->GetServer(); + // If auth is required, then send the encryption request: + if (Server->ShouldAuthenticate()) + { + cPacketizer Pkt(*this, 0x01); + Pkt.WriteString(Server->GetServerID()); + const AString & PubKeyDer = Server->GetPublicKeyDER(); + Pkt.WriteVarInt((short)PubKeyDer.size()); + Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size()); + Pkt.WriteVarInt(4); + Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) + m_Client->SetUsername(Username); + return; + } + + m_Client->HandleLogin(4, Username); +} + + + + + +void cProtocol180::HandlePacketAnimation(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Animation); + m_Client->HandleAnimation(Animation); +} + + + + + +void cProtocol180::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status); + + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + { + return; + } + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); + m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, static_cast(Face), Status); +} + + + + + +void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) +{ + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + { + return; + } + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); + cItem Item; + ReadItem(a_ByteBuffer, Item); + + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ); + m_Client->HandleRightClick(BlockX, BlockY, BlockZ, static_cast(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); +} + + + + + +void cProtocol180::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message); + m_Client->HandleChat(Message); +} + + + + + +void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); + HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags); + + m_Client->SetLocale(Locale); + // TODO: Handle other values +} + + + + + +void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID); + switch (ActionID) + { + case 0: + { + // Respawn + m_Client->HandleRespawn(); + break; + } + case 1: + { + // Request stats + const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); + SendStatistics(Manager); - case cCompositeChat::ptShowAchievement: - { - const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; - Part["translate"] = "chat.type.achievement"; + break; + } + case 2: + { + // Open Inventory achievement + m_Client->GetPlayer()->AwardAchievement(achOpenInv); + break; + } + } +} - Json::Value Ach; - Ach["action"] = "show_achievement"; - Ach["value"] = p.m_Text; - - Json::Value AchColourAndName; - AchColourAndName["color"] = "green"; - AchColourAndName["translate"] = p.m_Text; - AchColourAndName["hoverEvent"] = Ach; - Json::Value Extra; - Extra.append(AchColourAndName); - Json::Value Name; - Name["text"] = p.m_PlayerName; - Json::Value With; - With.append(Name); - With.append(Extra); - Part["with"] = With; - AddChatPartStyle(Part, p.m_Style); - break; - } - } - msg["extra"].append(Part); - } // for itr - Parts[] - - // Send the message to the client: - cPacketizer Pkt(*this, 0x02); - Pkt.WriteString(msg.toStyledString()); - Pkt.WriteChar(0); +void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); + cItem Item; + if (!ReadItem(a_ByteBuffer, Item)) + { + return; + } + m_Client->HandleCreativeInventory(SlotNum, Item); +} + + + + + +void cProtocol180::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID); + HANDLE_READ(a_ByteBuffer, ReadChar, char, Action); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost); + + switch (Action) + { + case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch + case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch + case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed + case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting + case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting + } +} + + + + + +void cProtocol180::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID); + m_Client->HandleKeepAlive((int)KeepAliveID); +} + + + + + +void cProtocol180::HandlePacketPlayer(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + // TODO: m_Client->HandlePlayerOnGround(IsOnGround); +} + + + + + +void cProtocol180::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); + + bool IsFlying = false, CanFly = false; + if ((Flags & 2) != 0) + { + IsFlying = true; + } + if ((Flags & 4) != 0) + { + CanFly = true; + } + + m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed); +} + + + + + +void cProtocol180::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround); +} + + + + + +void cProtocol180::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + 1.62, IsOnGround); +} + + + + + +void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); + m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround); +} + + + + + +void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + AString Data; + if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) + { + return; + } + m_Client->HandlePluginMessage(Channel, Data); +} + + + + + +void cProtocol180::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); + m_Client->HandleSlotSelected(SlotNum); +} + + + + + +void cProtocol180::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); + HANDLE_READ(a_ByteBuffer, ReadChar, char, Flags); + + if ((Flags & 0x2) != 0) + { + m_Client->HandleUnmount(); + } + else if ((Flags & 0x1) != 0) + { + m_Client->HandleSteerVehicle(Forward, Sideways); + } +} + + + + + +void cProtocol180::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, HasPosition); + + if (HasPosition) + { + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Position); + } + + m_Client->HandleTabCompletion(Text); +} + + + + + +void cProtocol180::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line1); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line2); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line3); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line4); + m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4); +} + + + + + +void cProtocol180::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type); + + switch (Type) + { + case 0: + { + m_Client->HandleUseEntity((int)EntityID, false); + break; + } + case 1: + { + m_Client->HandleUseEntity((int)EntityID, true); + break; + } + case 2: + { + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ); + + // TODO: Do anything + break; + } + default: + { + ASSERT(!"Unhandled use entity type!"); + return; + } + } +} + + + + + +void cProtocol180::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, WindowID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Enchantment); + + m_Client->HandleEnchantItem(WindowID, Enchantment); +} + + + + + +void cProtocol180::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Button); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode); + cItem Item; + ReadItem(a_ByteBuffer, Item); + + // Convert Button, Mode, SlotNum and HeldItem into eClickAction: + eClickAction Action; + switch ((Mode << 8) | Button) + { + case 0x0000: Action = (SlotNum != -999) ? caLeftClick : caLeftClickOutside; break; + case 0x0001: Action = (SlotNum != -999) ? caRightClick : caRightClickOutside; break; + case 0x0100: Action = caShiftLeftClick; break; + case 0x0101: Action = caShiftRightClick; break; + case 0x0200: Action = caNumber1; break; + case 0x0201: Action = caNumber2; break; + case 0x0202: Action = caNumber3; break; + case 0x0203: Action = caNumber4; break; + case 0x0204: Action = caNumber5; break; + case 0x0205: Action = caNumber6; break; + case 0x0206: Action = caNumber7; break; + case 0x0207: Action = caNumber8; break; + case 0x0208: Action = caNumber9; break; + case 0x0300: Action = caMiddleClick; break; + case 0x0400: Action = (SlotNum == -999) ? caLeftClickOutsideHoldNothing : caDropKey; break; + case 0x0401: Action = (SlotNum == -999) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break; + case 0x0500: Action = (SlotNum == -999) ? caLeftPaintBegin : caUnknown; break; + case 0x0501: Action = (SlotNum != -999) ? caLeftPaintProgress : caUnknown; break; + case 0x0502: Action = (SlotNum == -999) ? caLeftPaintEnd : caUnknown; break; + case 0x0504: Action = (SlotNum == -999) ? caRightPaintBegin : caUnknown; break; + case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break; + case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break; + case 0x0600: Action = caDblClick; break; + default: + { + LOGWARNING("Unhandled window click mode / button combination: %d (0x%x)", (Mode << 8) | Button, (Mode << 8) | Button); + Action = caUnknown; + break; + } + } + + m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item); +} + + + + + +void cProtocol180::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID); + m_Client->HandleWindowClose(WindowID); } -void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) +void cProtocol180::WritePacket(cByteBuffer & a_Packet) { - ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x04); // Entity Equipment packet - Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); - Pkt.WriteShort(a_SlotNum); - Pkt.WriteItem(a_Item);*/ + cCSLock Lock(m_CSPacket); + AString Pkt; + a_Packet.ReadAll(Pkt); + WriteVarInt((UInt32)Pkt.size()); + SendData(Pkt.data(), Pkt.size()); + Flush(); } -void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +void cProtocol180::SendData(const char * a_Data, size_t a_Size) { - // Send the Join Game packet: + if (m_IsEncrypted) { - cServer * Server = cRoot::Get()->GetServer(); - cPacketizer Pkt(*this, 0x01); // Join Game packet - Pkt.WriteInt(a_Player.GetUniqueID()); - Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 - Pkt.WriteChar((char)a_World.GetDimension()); - Pkt.WriteByte(2); // TODO: Difficulty (set to Normal) - Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60)); - Pkt.WriteString("default"); // Level type - wtf? - Pkt.WriteBool(false); // Reduced Debug Info - wtf? + Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) + while (a_Size > 0) + { + size_t NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size; + m_Encryptor.ProcessData(Encrypted, (Byte *)a_Data, NumBytes); + m_Client->SendData((const char *)Encrypted, NumBytes); + a_Size -= NumBytes; + a_Data += NumBytes; + } } - m_LastSentDimension = a_World.GetDimension(); - - // Send the spawn position: + else { - cPacketizer Pkt(*this, 0x05); // Spawn Position packet - Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); + m_Client->SendData(a_Data, a_Size); } - - // Send player abilities: - SendPlayerAbilities(); } @@ -752,7 +2357,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) AString Metadata; a_ByteBuffer.ReadAll(Metadata); - ParseItemMetadata(a_Item, Metadata, false); + ParseItemMetadata(a_Item, Metadata); return true; } @@ -760,45 +2365,69 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) -void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) +void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { - HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); - cItem Item; - if (!ReadItem(a_ByteBuffer, Item)) + // Parse into NBT: + cParsedNBT NBT(a_Metadata.data(), a_Metadata.size()); + if (!NBT.IsValid()) { + AString HexDump; + CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); + LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", a_Metadata.size(), HexDump.c_str()); return; } - m_Client->HandleCreativeInventory(SlotNum, Item); -} - - - - - -void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) -{ - HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID); - switch (ActionID) + + // Load enchantments and custom display names from the NBT data: + for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) { - case 0: + AString TagName = NBT.GetName(tag); + switch (NBT.GetType(tag)) { - // Respawn - m_Client->HandleRespawn(); - break; - } - case 1: - { - // Request stats - const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager(); - SendStatistics(Manager); - - break; - } - case 2: - { - // Open Inventory achievement - m_Client->GetPlayer()->AwardAchievement(achOpenInv); - break; + case TAG_List: + { + if ((TagName == "ench") || (TagName == "StoredEnchantments")) // Enchantments tags + { + EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); + } + break; + } + case TAG_Compound: + { + if (TagName == "display") // Custom name and lore tag + { + for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) + { + if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + { + a_Item.m_CustomName = NBT.GetString(displaytag); + } + else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + { + AString Lore; + + for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + { + AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;) + } + + a_Item.m_Lore = Lore; + } + } + } + else if ((TagName == "Fireworks") || (TagName == "Explosion")) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, NBT, tag, (ENUM_ITEM_ID)a_Item.m_ItemType); + } + break; + } + case TAG_Int: + { + if (TagName == "RepairCost") + { + a_Item.m_RepairCost = NBT.GetInt(tag); + } + } + default: LOGD("Unimplemented NBT data when parsing!"); break; } } } @@ -807,173 +2436,144 @@ void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) -void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) -{ - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - AString Data; - if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) - { - return; - } - m_Client->HandlePluginMessage(Channel, Data); -} - - - - - -void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) -{ - cServer * Server = cRoot::Get()->GetServer(); - AString ServerDescription = Server->GetDescription(); - int NumPlayers = Server->GetNumPlayers(); - int MaxPlayers = Server->GetMaxPlayers(); - AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); - - // Version: - Json::Value Version; - Version["name"] = "1.8"; - Version["protocol"] = 47; - - // Players: - Json::Value Players; - Players["online"] = NumPlayers; - Players["max"] = MaxPlayers; - // TODO: Add "sample" - - // Description: - Json::Value Description; - Description["text"] = ServerDescription.c_str(); - - // Create the response: - Json::Value ResponseValue; - ResponseValue["version"] = Version; - ResponseValue["players"] = Players; - ResponseValue["description"] = Description; - if (!Favicon.empty()) - { - ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); - } - - Json::StyledWriter Writer; - AString Response = Writer.write(ResponseValue); - - cPacketizer Pkt(*this, 0x00); // Response packet - Pkt.WriteString(Response); -} - - - - - -void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) +void cProtocol180::StartEncryption(const Byte * a_Key) { - AString Username; - if (!a_ByteBuffer.ReadVarUTF8String(Username)) - { - m_Client->Kick("Bad username"); - return; - } - - if (!m_Client->HandleHandshake(Username)) - { - // The client is not welcome here, they have been sent a Kick packet already - return; - } + m_Encryptor.Init(a_Key, a_Key); + m_Decryptor.Init(a_Key, a_Key); + m_IsEncrypted = true; + // Prepare the m_AuthServerID: + cSha1Checksum Checksum; cServer * Server = cRoot::Get()->GetServer(); - // If auth is required, then send the encryption request: - if (Server->ShouldAuthenticate()) - { - cPacketizer Pkt(*this, 0x01); - Pkt.WriteString(Server->GetServerID()); - const AString & PubKeyDer = Server->GetPublicKeyDER(); - Pkt.WriteVarInt((short)PubKeyDer.size()); - Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size()); - Pkt.WriteVarInt(4); - Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) - m_Client->SetUsername(Username); - return; - } - - m_Client->HandleLogin(4, Username); + const AString & ServerID = Server->GetServerID(); + Checksum.Update((const Byte *)ServerID.c_str(), ServerID.length()); + Checksum.Update(a_Key, 16); + Checksum.Update((const Byte *)Server->GetPublicKeyDER().data(), Server->GetPublicKeyDER().size()); + Byte Digest[20]; + Checksum.Finalize(Digest); + cSha1Checksum::DigestToJava(Digest, m_AuthServerID); } -void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) +void cProtocol180::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) { - UInt32 EncKeyLength, EncNonceLength; - a_ByteBuffer.ReadVarInt(EncKeyLength); - AString EncKey; - if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) - { - return; - } - a_ByteBuffer.ReadVarInt(EncNonceLength); - AString EncNonce; - if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) - { - return; - } - if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) - { - LOGD("Too long encryption"); - m_Client->Kick("Hacked client"); - return; - } - - // Decrypt EncNonce using privkey - cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); - Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; - int res = rsaDecryptor.Decrypt((const Byte *)EncNonce.data(), EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); - if (res != 4) - { - LOGD("Bad nonce length: got %d, exp %d", res, 4); - m_Client->Kick("Hacked client"); - return; - } - if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) - { - LOGD("Bad nonce value"); - m_Client->Kick("Hacked client"); - return; - } - - // Decrypt the symmetric encryption key using privkey: - Byte DecryptedKey[MAX_ENC_LEN]; - res = rsaDecryptor.Decrypt((const Byte *)EncKey.data(), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); - if (res != 16) + size_t len = a_PartStyle.length(); + for (size_t i = 0; i < len; i++) { - LOGD("Bad key length"); - m_Client->Kick("Hacked client"); - return; - } - - StartEncryption(DecryptedKey); - m_Client->HandleLogin(4, m_Client->GetUsername()); + switch (a_PartStyle[i]) + { + case 'b': + { + // bold + a_Value["bold"] = Json::Value(true); + break; + } + + case 'i': + { + // italic + a_Value["italic"] = Json::Value(true); + break; + } + + case 'u': + { + // Underlined + a_Value["underlined"] = Json::Value(true); + break; + } + + case 's': + { + // strikethrough + a_Value["strikethrough"] = Json::Value(true); + break; + } + + case 'o': + { + // obfuscated + a_Value["obfuscated"] = Json::Value(true); + break; + } + + case '@': + { + // Color, specified by the next char: + i++; + if (i >= len) + { + // String too short, didn't contain a color + break; + } + switch (a_PartStyle[i]) + { + case '0': a_Value["color"] = Json::Value("black"); break; + case '1': a_Value["color"] = Json::Value("dark_blue"); break; + case '2': a_Value["color"] = Json::Value("dark_green"); break; + case '3': a_Value["color"] = Json::Value("dark_aqua"); break; + case '4': a_Value["color"] = Json::Value("dark_red"); break; + case '5': a_Value["color"] = Json::Value("dark_purple"); break; + case '6': a_Value["color"] = Json::Value("gold"); break; + case '7': a_Value["color"] = Json::Value("gray"); break; + case '8': a_Value["color"] = Json::Value("dark_gray"); break; + case '9': a_Value["color"] = Json::Value("blue"); break; + case 'a': a_Value["color"] = Json::Value("green"); break; + case 'b': a_Value["color"] = Json::Value("aqua"); break; + case 'c': a_Value["color"] = Json::Value("red"); break; + case 'd': a_Value["color"] = Json::Value("light_purple"); break; + case 'e': a_Value["color"] = Json::Value("yellow"); break; + case 'f': a_Value["color"] = Json::Value("white"); break; + } // switch (color) + } // case '@' + } // switch (Style[i]) + } // for i - a_PartStyle[] } -void cProtocol180::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) +//////////////////////////////////////////////////////////////////////////////// +// cProtocol180::cPacketizer: + +cProtocol180::cPacketizer::~cPacketizer() { - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); - HANDLE_READ(a_ByteBuffer, ReadChar, char, Flags); + AString DataToSend; - if ((Flags & 0x2) != 0) + // Send the packet length + UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace(); + + if (m_Protocol.m_State == 3) { - m_Client->HandleUnmount(); + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen + 1); + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); } - else if ((Flags & 0x1) != 0) + else { - m_Client->HandleSteerVehicle(Forward, Sideways); + m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); + } + m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); + m_Protocol.SendData(DataToSend.data(), DataToSend.size()); + m_Protocol.m_OutPacketLenBuffer.CommitRead(); + + // Send the packet data: + m_Out.ReadAll(DataToSend); + m_Protocol.SendData(DataToSend.data(), DataToSend.size()); + m_Out.CommitRead(); + + // Log the comm into logfile: + if (g_ShouldLogCommOut) + { + AString Hex; + ASSERT(DataToSend.size() > 0); + CreateHexDump(Hex, DataToSend.data() + 1, DataToSend.size() - 1, 16); + m_Protocol.m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload:\n%s\n", + DataToSend[0], DataToSend[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str() + ); } } @@ -981,171 +2581,518 @@ void cProtocol180::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) -void cProtocol180::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteItem(const cItem & a_Item) { - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID); - HANDLE_READ(a_ByteBuffer, ReadChar, char, Action); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost); + short ItemType = a_Item.m_ItemType; + ASSERT(ItemType >= -1); // Check validity of packets in debug runtime + if (ItemType <= 0) + { + // Fix, to make sure no invalid values are sent. + ItemType = -1; + } + + if (a_Item.IsEmpty()) + { + WriteShort(-1); + return; + } + + WriteShort(ItemType); + WriteByte (a_Item.m_ItemCount); + WriteShort(a_Item.m_ItemDamage); + + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR)) + { + WriteChar(0); + return; + } - switch (Action) + // Send the enchantments and custom names: + cFastNBTWriter Writer; + if (a_Item.m_RepairCost != 0) { - case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch - case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch - case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed - case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting - case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting + Writer.AddInt("RepairCost", a_Item.m_RepairCost); + } + if (!a_Item.m_Enchantments.IsEmpty()) + { + const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; + EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); + } + if (!a_Item.IsBothNameAndLoreEmpty()) + { + Writer.BeginCompound("display"); + if (!a_Item.IsCustomNameEmpty()) + { + Writer.AddString("Name", a_Item.m_CustomName.c_str()); + } + if (!a_Item.IsLoreEmpty()) + { + Writer.BeginList("Lore", TAG_String); + + AStringVector Decls = StringSplit(a_Item.m_Lore, "`"); + for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr) + { + if (itr->empty()) + { + // The decl is empty (two `s), ignore + continue; + } + Writer.AddString("", itr->c_str()); + } + + Writer.EndList(); + } + Writer.EndCompound(); + } + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); } + Writer.Finish(); + + AString Result = Writer.GetResult(); + if (Result.size() == 0) + { + WriteChar(0); + return; + } + WriteBuf(Result.data(), Result.size()); } -void cProtocol180::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEntity) { - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type); + cFastNBTWriter Writer; - switch (Type) + switch (a_BlockEntity.GetBlockType()) { - case 0: + case E_BLOCK_BEACON: { - m_Client->HandleUseEntity((int)EntityID, false); + cBeaconEntity & BeaconEntity = (cBeaconEntity &)a_BlockEntity; + + Writer.AddInt("x", BeaconEntity.GetPosX()); + Writer.AddInt("y", BeaconEntity.GetPosY()); + Writer.AddInt("z", BeaconEntity.GetPosZ()); + Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); + Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); + Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); + Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; } - case 1: + case E_BLOCK_COMMAND_BLOCK: { - m_Client->HandleUseEntity((int)EntityID, true); + cCommandBlockEntity & CommandBlockEntity = (cCommandBlockEntity &)a_BlockEntity; + + Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this + Writer.AddInt("SuccessCount", CommandBlockEntity.GetResult()); + Writer.AddInt("x", CommandBlockEntity.GetPosX()); + Writer.AddInt("y", CommandBlockEntity.GetPosY()); + Writer.AddInt("z", CommandBlockEntity.GetPosZ()); + Writer.AddString("Command", CommandBlockEntity.GetCommand().c_str()); + // You can set custom names for windows in Vanilla + // For a command block, this would be the 'name' prepended to anything it outputs into global chat + // MCS doesn't have this, so just leave it @ '@'. (geddit?) + Writer.AddString("CustomName", "@"); + Writer.AddString("id", "Control"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + + if (!CommandBlockEntity.GetLastOutput().empty()) + { + AString Output; + Printf(Output, "{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str()); + + Writer.AddString("LastOutput", Output.c_str()); + } break; } - case 2: + case E_BLOCK_HEAD: { - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ); - - // TODO: Do anything + cMobHeadEntity & MobHeadEntity = (cMobHeadEntity &)a_BlockEntity; + + Writer.AddInt("x", MobHeadEntity.GetPosX()); + Writer.AddInt("y", MobHeadEntity.GetPosY()); + Writer.AddInt("z", MobHeadEntity.GetPosZ()); + Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF); + Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF); + Writer.AddString("ExtraType", MobHeadEntity.GetOwner().c_str()); + Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; } - default: + case E_BLOCK_FLOWER_POT: { - ASSERT(!"Unhandled use entity type!"); - return; + cFlowerPotEntity & FlowerPotEntity = (cFlowerPotEntity &)a_BlockEntity; + + Writer.AddInt("x", FlowerPotEntity.GetPosX()); + Writer.AddInt("y", FlowerPotEntity.GetPosY()); + Writer.AddInt("z", FlowerPotEntity.GetPosZ()); + Writer.AddInt("Item", (Int32) FlowerPotEntity.GetItem().m_ItemType); + Writer.AddInt("Data", (Int32) FlowerPotEntity.GetItem().m_ItemDamage); + Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + break; } + default: break; } -} - - + Writer.Finish(); - -void cProtocol180::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) -{ - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID); - m_Client->HandleKeepAlive((int)KeepAliveID); + AString Compressed; + CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); + WriteShort((short)Compressed.size()); + WriteBuf(Compressed.data(), Compressed.size()); } -void cProtocol180::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteByteAngle(double a_Angle) { - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + 1.62, IsOnGround); + WriteByte((char)(255 * a_Angle / 360)); } -void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteFPInt(double a_Value) { - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); - HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); - HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround); - m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround); + int Value = (int)(a_Value * 32); + WriteInt(Value); } -void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance); - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); - HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags); + // Common metadata: + Byte Flags = 0; + if (a_Entity.IsOnFire()) + { + Flags |= 0x01; + } + if (a_Entity.IsCrouched()) + { + Flags |= 0x02; + } + if (a_Entity.IsSprinting()) + { + Flags |= 0x08; + } + if (a_Entity.IsRclking()) + { + Flags |= 0x10; + } + if (a_Entity.IsInvisible()) + { + Flags |= 0x20; + } + WriteByte(0); // Byte(0) + index 0 + WriteByte(Flags); - m_Client->SetLocale(Locale); - // TODO: Handle other values -} - - - - - -void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) -{ - int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + switch (a_Entity.GetEntityType()) { - return; + case cEntity::etPlayer: break; // TODO? + case cEntity::etPickup: + { + WriteByte((5 << 5) | 10); // Slot(5) + index 10 + WriteItem(((const cPickup &)a_Entity).GetItem()); + break; + } + case cEntity::etMinecart: + { + WriteByte(0x51); + + // The following expression makes Minecarts shake more with less health or higher damage taken + // It gets half the maximum health, and takes it away from the current health minus the half health: + /* + Health: 5 | 3 - (5 - 3) = 1 (shake power) + Health: 3 | 3 - (3 - 3) = 3 + Health: 1 | 3 - (1 - 3) = 5 + */ + WriteInt((((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * ((const cMinecart &)a_Entity).LastDamage()) * 4); + WriteByte(0x52); + WriteInt(1); // Shaking direction, doesn't seem to affect anything + WriteByte(0x73); + WriteFloat((float)(((const cMinecart &)a_Entity).LastDamage() + 10)); // Damage taken / shake effect multiplyer + + if (((cMinecart &)a_Entity).GetPayload() == cMinecart::mpNone) + { + cRideableMinecart & RideableMinecart = ((cRideableMinecart &)a_Entity); + const cItem & MinecartContent = RideableMinecart.GetContent(); + if (!MinecartContent.IsEmpty()) + { + WriteByte(0x54); + int Content = MinecartContent.m_ItemType; + Content |= MinecartContent.m_ItemDamage << 8; + WriteInt(Content); + WriteByte(0x55); + WriteInt(RideableMinecart.GetBlockHeight()); + WriteByte(0x56); + WriteByte(1); + } + } + else if (((cMinecart &)a_Entity).GetPayload() == cMinecart::mpFurnace) + { + WriteByte(0x10); + WriteByte(((const cMinecartWithFurnace &)a_Entity).IsFueled() ? 1 : 0); + } + break; + } + case cEntity::etProjectile: + { + cProjectileEntity & Projectile = (cProjectileEntity &)a_Entity; + switch (Projectile.GetProjectileKind()) + { + case cProjectileEntity::pkArrow: + { + WriteByte(0x10); + WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); + break; + } + case cProjectileEntity::pkFirework: + { + WriteByte(0xA8); + WriteItem(((const cFireworkEntity &)a_Entity).GetItem()); + break; + } + default: break; + } + break; + } + case cEntity::etMonster: + { + WriteMobMetadata((const cMonster &)a_Entity); + break; + } + case cEntity::etItemFrame: + { + cItemFrame & Frame = (cItemFrame &)a_Entity; + WriteByte(0xA2); + WriteItem(Frame.GetItem()); + WriteByte(0x3); + WriteByte(Frame.GetRotation()); + break; + } + default: break; } - - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); - cItem Item; - ReadItem(a_ByteBuffer, Item); - - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ); - m_Client->HandleRightClick(BlockX, BlockY, BlockZ, static_cast(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); } -void cProtocol180::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) { - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status); - - int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + switch (a_Mob.GetMobType()) { - return; - } + case cMonster::mtCreeper: + { + WriteByte(0x10); + WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); + WriteByte(0x11); + WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); + break; + } + + case cMonster::mtBat: + { + WriteByte(0x10); + WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); + break; + } + + case cMonster::mtPig: + { + WriteByte(0x10); + WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); + break; + } + + case cMonster::mtVillager: + { + WriteByte(0x50); + WriteInt(((const cVillager &)a_Mob).GetVilType()); + break; + } + + case cMonster::mtZombie: + { + WriteByte(0x0c); + WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); + WriteByte(0x0d); + WriteByte(((const cZombie &)a_Mob).IsVillagerZombie() ? 1 : 0); + WriteByte(0x0e); + WriteByte(((const cZombie &)a_Mob).IsConverting() ? 1 : 0); + break; + } + + case cMonster::mtGhast: + { + WriteByte(0x10); + WriteByte(((const cGhast &)a_Mob).IsCharging()); + break; + } + + case cMonster::mtWolf: + { + const cWolf & Wolf = (const cWolf &)a_Mob; + Byte WolfStatus = 0; + if (Wolf.IsSitting()) + { + WolfStatus |= 0x1; + } + if (Wolf.IsAngry()) + { + WolfStatus |= 0x2; + } + if (Wolf.IsTame()) + { + WolfStatus |= 0x4; + } + WriteByte(0x10); + WriteByte(WolfStatus); + + WriteByte(0x72); + WriteFloat((float)(a_Mob.GetHealth())); + WriteByte(0x13); + WriteByte(Wolf.IsBegging() ? 1 : 0); + WriteByte(0x14); + WriteByte(Wolf.GetCollarColor()); + break; + } + + case cMonster::mtSheep: + { + WriteByte(0x10); + Byte SheepMetadata = 0; + SheepMetadata = ((const cSheep &)a_Mob).GetFurColor(); + if (((const cSheep &)a_Mob).IsSheared()) + { + SheepMetadata |= 0x10; + } + WriteByte(SheepMetadata); + break; + } + + case cMonster::mtEnderman: + { + WriteByte(0x10); + WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); + WriteByte(0x11); + WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); + WriteByte(0x12); + WriteByte(((const cEnderman &)a_Mob).IsScreaming() ? 1 : 0); + break; + } + + case cMonster::mtSkeleton: + { + WriteByte(0x0d); + WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); + break; + } + + case cMonster::mtWitch: + { + WriteByte(0x15); + WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); + break; + } - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); - m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, static_cast(Face), Status); + case cMonster::mtWither: + { + WriteByte(0x54); // Int at index 20 + WriteInt(((const cWither &)a_Mob).GetWitherInvulnerableTicks()); + WriteByte(0x66); // Float at index 6 + WriteFloat((float)(a_Mob.GetHealth())); + break; + } + + case cMonster::mtSlime: + { + WriteByte(0x10); + WriteByte(((const cSlime &)a_Mob).GetSize()); + break; + } + + case cMonster::mtMagmaCube: + { + WriteByte(0x10); + WriteByte(((const cMagmaCube &)a_Mob).GetSize()); + break; + } + + case cMonster::mtHorse: + { + const cHorse & Horse = (const cHorse &)a_Mob; + int Flags = 0; + if (Horse.IsTame()) + { + Flags |= 0x02; + } + if (Horse.IsSaddled()) + { + Flags |= 0x04; + } + if (Horse.IsChested()) + { + Flags |= 0x08; + } + if (Horse.IsBaby()) + { + Flags |= 0x10; + } + if (Horse.IsEating()) + { + Flags |= 0x20; + } + if (Horse.IsRearing()) + { + Flags |= 0x40; + } + if (Horse.IsMthOpen()) + { + Flags |= 0x80; + } + WriteByte(0x50); // Int at index 16 + WriteInt(Flags); + WriteByte(0x13); // Byte at index 19 + WriteByte(Horse.GetHorseType()); + WriteByte(0x54); // Int at index 20 + int Appearance = 0; + Appearance = Horse.GetHorseColor(); + Appearance |= Horse.GetHorseStyle() << 8; + WriteInt(Appearance); + WriteByte(0x56); // Int at index 22 + WriteInt(Horse.GetHorseArmour()); + break; + } + } // switch (a_Mob.GetType()) } -void cProtocol180::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) +void cProtocol180::cPacketizer::WriteEntityProperties(const cEntity & a_Entity) { - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text); - HANDLE_READ(a_ByteBuffer, ReadBool, bool, HasPosition); - - if (HasPosition) + if (!a_Entity.IsMob()) { - HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Position); + // No properties for anything else than mobs + WriteInt(0); + return; } - m_Client->HandleTabCompletion(Text); -} + // const cMonster & Mob = (const cMonster &)a_Entity; + // TODO: Send properties and modifiers based on the mob type + + WriteInt(0); // NumProperties +} diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index a3478e674..f9d5a24dd 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -4,7 +4,7 @@ /* Declares the 1.8.x protocol classes: - cProtocol180 - - release 1.8 protocol (#47) + - release 1.8.0 protocol (#47) (others may be added later in the future for the 1.8 release series) */ @@ -15,7 +15,6 @@ Declares the 1.8.x protocol classes: #pragma once #include "Protocol.h" -#include "Protocol17x.h" #include "../ByteBuffer.h" #ifdef _MSC_VER @@ -31,6 +30,9 @@ Declares the 1.8.x protocol classes: #pragma warning(pop) #endif +#include "PolarSSL++/AesCfb128Decryptor.h" +#include "PolarSSL++/AesCfb128Encryptor.h" + @@ -46,76 +48,273 @@ namespace Json class cProtocol180 : - public cProtocol176 + public cProtocol { - typedef cProtocol176 super; + typedef cProtocol super; public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + + /** Called when client sends some data: */ + virtual void DataReceived(const char * a_Data, size_t a_Size) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendLoginSuccess (void) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override {} - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {} - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + /** Sending stuff to clients (alphabetically sorted): */ + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendChat (const cCompositeChat & a_Message) override; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendEntityHeadLook (const cEntity & a_Entity) override; + virtual void SendEntityLook (const cEntity & a_Entity) override; + virtual void SendEntityMetadata (const cEntity & a_Entity) override; + virtual void SendEntityProperties (const cEntity & a_Entity) override; virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityLook(const cEntity & a_Entity) override; - virtual void SendTeleportEntity(const cEntity & a_Entity) override; - virtual void SendEntityHeadLook(const cEntity & a_Entity) override; - virtual void SendEntityMetadata(const cEntity & a_Entity) override; - virtual void SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) override; - virtual void SendEntityProperties(const cEntity & a_Entity) override; - virtual void SendKeepAlive(int a_PingID) override; - virtual void SendHealth(void) override; - virtual void SendExperience(void) override; - virtual void SendPaintingSpawn(const cPainting & a_Painting) override; - virtual void SendPluginMessage(const AString & a_Channel, const AString & a_Message) override; - virtual void SendUnloadChunk(int a_ChunkX, int a_ChunkZ) override; - virtual void SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat(const AString & a_Message) override; - virtual void SendChat(const cCompositeChat & a_Message) override; - virtual void SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) override {} - virtual void SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendLogin(const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendKeepAlive (int a_PingID) override; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendLoginSuccess (void) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendPlayerAbilities (void) override; + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerMaxSpeed (void) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendPlayerPosition (void) override; + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnMob (const cMonster & a_Mob) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; + virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendTabCompletionResults(const AStringVector & a_Results) override; + virtual void SendTeleportEntity (const cEntity & a_Entity) override; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendWeather (eWeather a_Weather) override; + virtual void SendWholeInventory (const cWindow & a_Window) override; + virtual void SendWindowClose (const cWindow & a_Window) override; + virtual void SendWindowOpen (const cWindow & a_Window) override; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + + virtual AString GetAuthServerID(void) override { return m_AuthServerID; } protected: - virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) override; + /** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */ + class cPacketizer + { + public: + cPacketizer(cProtocol180 & a_Protocol, UInt32 a_PacketType) : + m_Protocol(a_Protocol), + m_Out(a_Protocol.m_OutPacketBuffer), + m_Lock(a_Protocol.m_CSPacket) + { + m_Out.WriteVarInt(a_PacketType); + } + + ~cPacketizer(); - virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; + void WriteBool(bool a_Value) + { + m_Out.WriteBool(a_Value); + } + + void WriteByte(Byte a_Value) + { + m_Out.WriteByte(a_Value); + } + + void WriteChar(char a_Value) + { + m_Out.WriteChar(a_Value); + } + + void WriteShort(short a_Value) + { + m_Out.WriteBEShort(a_Value); + } + + void WriteInt(int a_Value) + { + m_Out.WriteBEInt(a_Value); + } + + void WriteInt64(Int64 a_Value) + { + m_Out.WriteBEInt64(a_Value); + } + + void WriteFloat(float a_Value) + { + m_Out.WriteBEFloat(a_Value); + } + + void WriteDouble(double a_Value) + { + m_Out.WriteBEDouble(a_Value); + } + + void WriteVarInt(UInt32 a_Value) + { + m_Out.WriteVarInt(a_Value); + } + + void WriteString(const AString & a_Value) + { + m_Out.WriteVarUTF8String(a_Value); + } - // Packet handlers while in the Login state (m_State == 2): - virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override; + void WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ) + { + m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + } + + void WriteBuf(const char * a_Data, size_t a_Size) + { + m_Out.Write(a_Data, a_Size); + } + + void WriteItem(const cItem & a_Item); + void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte + void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer + void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f + void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob + void WriteEntityProperties(const cEntity & a_Entity); // Writes the entity properties for the specified entity, including the Count field + void WriteBlockEntity(const cBlockEntity & a_BlockEntity); + + protected: + cProtocol180 & m_Protocol; + cByteBuffer & m_Out; + cCSLock m_Lock; + } ; + + AString m_ServerAddress; + + UInt16 m_ServerPort; + + AString m_AuthServerID; + + /** State of the protocol. 1 = status, 2 = login, 3 = game */ + UInt32 m_State; + + /** Buffer for the received data */ + cByteBuffer m_ReceivedData; + + /** Buffer for composing the outgoing packets, through cPacketizer */ + cByteBuffer m_OutPacketBuffer; + + /** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */ + cByteBuffer m_OutPacketLenBuffer; + + bool m_IsEncrypted; + + cAesCfb128Decryptor m_Decryptor; + cAesCfb128Encryptor m_Encryptor; + + /** The logfile where the comm is logged, when g_ShouldLogComm is true */ + cFile m_CommLogFile; + + /** The dimension that was last sent to a player in a Respawn or Login packet. + Used to avoid Respawning into the same dimension, which confuses the client. */ + eDimension m_LastSentDimension; + + + /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ + void AddReceivedData(const char * a_Data, size_t a_Size); + + /** Reads and handles the packet. The packet length and type have already been read. + Returns true if the packet was understood, false if it was an unknown packet + */ + bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType); + + // Packet handlers while in the Status state (m_State == 1): + void HandlePacketStatusPing(cByteBuffer & a_ByteBuffer); + void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer); + // Packet handlers while in the Login state (m_State == 2): + void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); + void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); + // Packet handlers while in the Game state (m_State == 3): - virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override; - virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)override; - virtual void HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) override; -} ; + void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); + void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); + void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); + void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); + void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); + void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); + void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayer (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); + void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); + void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer); + void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); + void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); + void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer); + void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); + void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); + void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); + void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); + + + /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */ + void WritePacket(cByteBuffer & a_Packet); + + /** Sends the data to the client, encrypting them if needed. */ + virtual void SendData(const char * a_Data, size_t a_Size) override; + void SendCompass(const cWorld & a_World); + + /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); + + /** Parses item metadata as read by ReadItem(), into the item enchantments. */ + void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); + + void StartEncryption(const Byte * a_Key); + + /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */ + void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle); +} ; -- cgit v1.2.3 From 4bdf9256f24448717dfbcc6c16186675a0bd54cf Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 8 Sep 2014 18:56:27 +0100 Subject: Fixed a few compile warnings --- src/World.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index e669f6fa0..319d5851f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1592,9 +1592,9 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy MTRand r1; for (int i = 0; i < 60; i++) { - int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; - int OfsY = r1.randInt(3) + r1.randInt(3) - 3; - int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + int OfsX = static_cast(r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; + int OfsY = static_cast(r1.randInt(3) + r1.randInt(3)) - 3; + int OfsZ = static_cast(r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3; BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ); if (Ground != E_BLOCK_GRASS) { @@ -2844,7 +2844,7 @@ bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, co { AString m_Command; public: - cUpdateCommandBlock(const AString & a_Command) : m_Command(a_Command) {} + cUpdateCommandBlock(const AString & a_CallbackCommand) : m_Command(a_CallbackCommand) {} virtual bool Item(cCommandBlockEntity * a_CommandBlock) override { @@ -3319,20 +3319,25 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", IsWater ? 1 : 2); int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", IsWater ? 5 : 30); int NumNeighborsForSource = a_IniFile.GetValueSetI(SimulatorSectionName, "NumNeighborsForSource", IsWater ? 2 : -1); + + if ((Falloff > 15) || (Falloff < 0)) + { + LOGWARNING("Falloff for %s simulator is out of range, assuming default of %d", a_FluidName, IsWater ? 1 : 2); + } if (NoCaseCompare(SimulatorName, "floody") == 0) { - res = new cFloodyFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + res = new cFloodyFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, static_cast(Falloff), TickDelay, NumNeighborsForSource); } else if (NoCaseCompare(SimulatorName, "vanilla") == 0) { - res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, static_cast(Falloff), TickDelay, NumNeighborsForSource); } else { // The simulator name doesn't match anything we have, issue a warning: LOGWARNING("%s [Physics]:%s specifies an unknown simulator, using the default \"Vanilla\".", GetIniFileName().c_str(), SimulatorNameKey.c_str()); - res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, static_cast(Falloff), TickDelay, NumNeighborsForSource); } } @@ -3442,9 +3447,9 @@ void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World) public cPlayerListCallback { public: - cPlayerCallback(std::vector & a_SendQueue, cWorld & a_World) : + cPlayerCallback(std::vector & a_SendQueue, cWorld & a_CallbackWorld) : m_SendQueue(a_SendQueue), - m_World(a_World) + m_World(a_CallbackWorld) { } -- cgit v1.2.3 From 2c945c8818a19405c566be1fcb6367a69b0a60c8 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 8 Sep 2014 19:07:45 +0100 Subject: TimeOfDay does not need to be an Int64 --- src/Blocks/WorldInterface.h | 4 ++-- src/World.cpp | 2 +- src/World.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index d1c6f9bfc..b43d011d8 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -17,7 +17,7 @@ class cWorldInterface public: virtual ~cWorldInterface() {} - virtual Int64 GetTimeOfDay(void) const = 0; + virtual int GetTimeOfDay(void) const = 0; virtual Int64 GetWorldAge(void) const = 0; virtual eDimension GetDimension(void) const = 0; @@ -44,7 +44,7 @@ public: /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ virtual bool ForEachPlayer(cItemCallback & a_Callback) = 0; - virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0; + virtual void SetTimeOfDay(int a_TimeOfDay) = 0; /** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */ virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) = 0; diff --git a/src/World.cpp b/src/World.cpp index 319d5851f..e6f967a1b 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -876,7 +876,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_TimeOfDaySecs -= 1200.0; } - m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); + m_TimeOfDay = static_cast(m_TimeOfDaySecs * 20.0); // Updates the sky darkness based on current time of day UpdateSkyDarkness(); diff --git a/src/World.h b/src/World.h index 6316c6811..274bd2dcf 100644 --- a/src/World.h +++ b/src/World.h @@ -157,14 +157,14 @@ public: } virtual Int64 GetWorldAge (void) const override { return m_WorldAge; } - virtual Int64 GetTimeOfDay(void) const override { return m_TimeOfDay; } + virtual int GetTimeOfDay(void) const override { return m_TimeOfDay; } void SetTicksUntilWeatherChange(int a_WeatherInterval) { m_WeatherInterval = a_WeatherInterval; } - virtual void SetTimeOfDay(Int64 a_TimeOfDay) override + virtual void SetTimeOfDay(int a_TimeOfDay) override { m_TimeOfDay = a_TimeOfDay; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; @@ -888,7 +888,7 @@ private: double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs - Int64 m_TimeOfDay; // Time in ticks, calculated off of m_TimeOfDaySecs + int m_TimeOfDay; // Time in ticks, calculated off of m_TimeOfDaySecs Int64 m_LastTimeUpdate; // The tick in which the last time update has been sent. Int64 m_LastUnload; // The last WorldAge (in ticks) in which unloading was triggerred Int64 m_LastSave; // The last WorldAge (in ticks) in which save-all was triggerred -- cgit v1.2.3 From 76fa3a7ccd69aee7293a19dc06c327020d3cf908 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 8 Sep 2014 20:12:43 +0200 Subject: More fixes. --- src/ClientHandle.cpp | 12 +----------- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol18x.cpp | 5 +++++ 3 files changed, 7 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 4c36dec4d..a614d5597 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1198,19 +1198,9 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cWorld * World = m_Player->GetWorld(); - // 1.8 protocol fix - if ((int)a_BlockFace == 255) - { - a_BlockFace = BLOCK_FACE_NONE; - } - if ( (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block - ( - (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || // The block is too far away - (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || - (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) - ) + ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() >= 5) ) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 0b94cb144..af1dd06a5 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2560,7 +2560,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR)) { - WriteChar(0); + WriteShort(-1); return; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 1793583a2..46773a438 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1908,6 +1908,11 @@ void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) } HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); + if (Face == 255) + { + Face = 0; + } + cItem Item; ReadItem(a_ByteBuffer, Item); -- cgit v1.2.3 From fb20c2eb854799972822c702bc12fb5ca577897c Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 8 Sep 2014 19:15:29 +0100 Subject: FIxed a couple more warnings --- src/World.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index e6f967a1b..1d0969dfa 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -757,6 +757,11 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30"); break; } + case dimNotSet: + { + assert(!"Dimension not set"); + break; + } } } @@ -772,6 +777,7 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile) case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break; case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break; case dimEnd: DefaultMonsters = "enderman"; break; + case dimNotSet: assert(!"Dimension not set"); break; } m_bAnimals = a_IniFile.GetValueSetB("Monsters", "AnimalsOn", true); @@ -1130,7 +1136,7 @@ void cWorld::UpdateSkyDarkness(void) } else if (TempTime <= TIME_NIGHT_START) { - m_SkyDarkness = (TIME_NIGHT_START - TempTime) / TIME_SPAWN_DIVISOR; + m_SkyDarkness = static_cast((TIME_NIGHT_START - TempTime) / TIME_SPAWN_DIVISOR); } else if (TempTime <= TIME_NIGHT_END) { @@ -1138,7 +1144,7 @@ void cWorld::UpdateSkyDarkness(void) } else { - m_SkyDarkness = (TIME_SUNRISE - TempTime) / TIME_SPAWN_DIVISOR; + m_SkyDarkness = static_cast((TIME_SUNRISE - TempTime) / TIME_SPAWN_DIVISOR); } } -- cgit v1.2.3 From bd810b80a6df668cb6cb44519d8a533544163bfd Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 8 Sep 2014 21:31:47 +0100 Subject: use the correct ASSERT --- src/World.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 1d0969dfa..b7045c7f4 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -759,7 +759,7 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile) } case dimNotSet: { - assert(!"Dimension not set"); + ASSERT(!"Dimension not set"); break; } } @@ -777,7 +777,7 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile) case dimOverworld: DefaultMonsters = "bat, cavespider, chicken, cow, creeper, enderman, horse, mooshroom, ocelot, pig, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie"; break; case dimNether: DefaultMonsters = "blaze, ghast, magmacube, skeleton, zombie, zombiepigman"; break; case dimEnd: DefaultMonsters = "enderman"; break; - case dimNotSet: assert(!"Dimension not set"); break; + case dimNotSet: ASSERT(!"Dimension not set"); break; } m_bAnimals = a_IniFile.GetValueSetB("Monsters", "AnimalsOn", true); -- cgit v1.2.3 From 4b1f4e8d7ecaed0cc9c4dffbf58c5665183297c7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 9 Sep 2014 01:52:51 +0200 Subject: 1.8: Added new uuid field. --- src/ClientHandle.cpp | 42 +++++++++++++++++++++++++----------------- src/Protocol/Protocol18x.cpp | 17 +++++++++++++++++ src/Protocol/Protocol18x.h | 2 ++ 3 files changed, 44 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index a614d5597..e91644fbc 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1192,6 +1192,8 @@ void cClientHandle::FinishDigAnimation() void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem) { + // TODO: Rewrite this function + LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s", a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str() ); @@ -1204,14 +1206,17 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - if (a_BlockY < cChunkDef::Height - 1) + if ((a_BlockX >= 0) && (a_BlockY >= 0) && (a_BlockZ >= 0)) { - World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things - } - if (a_BlockY > 0) - { - World->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, m_Player); // 2 block high things + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + if (a_BlockY < cChunkDef::Height - 1) + { + World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things + } + if (a_BlockY > 0) + { + World->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, m_Player); // 2 block high things + } } m_Player->GetInventory().SendEquippedSlot(); return; @@ -1221,17 +1226,20 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { // A plugin doesn't agree with the action, replace the block on the client and quit: - cChunkInterface ChunkInterface(World->GetChunkMap()); - BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); - BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - - if (a_BlockFace != BLOCK_FACE_NONE) + if ((a_BlockX >= 0) && (a_BlockY >= 0) && (a_BlockZ >= 0)) { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things - m_Player->GetInventory().SendEquippedSlot(); + cChunkInterface ChunkInterface(World->GetChunkMap()); + BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); + BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + + if (a_BlockFace != BLOCK_FACE_NONE) + { + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things + m_Player->GetInventory().SendEquippedSlot(); + } } return; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 46773a438..60501a5b5 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2586,6 +2586,23 @@ cProtocol180::cPacketizer::~cPacketizer() +void cProtocol180::cPacketizer::WriteUUID(const AString & a_UUID) +{ + AString UUID_1 = a_UUID.substr(0, a_UUID.length() / 2); + AString UUID_2 = a_UUID.substr(a_UUID.length() / 2); + + UInt64 Value_1, Value_2; + sscanf(UUID_1.c_str(), "%llx", &Value_1); + sscanf(UUID_2.c_str(), "%llx", &Value_2); + + WriteInt64((Int64)Value_1); + WriteInt64((Int64)Value_2); +} + + + + + void cProtocol180::cPacketizer::WriteItem(const cItem & a_Item) { short ItemType = a_Item.m_ItemType; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index f9d5a24dd..207af0b44 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -204,6 +204,8 @@ protected: m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ); } + void WriteUUID(const AString & a_UUID); + void WriteBuf(const char * a_Data, size_t a_Size) { m_Out.Write(a_Data, a_Size); -- cgit v1.2.3 From d1d4f2146e12222071041db7088073dc4a90eb61 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 9 Sep 2014 01:54:40 +0200 Subject: PlayerSpawn packet: Send the correct uuid. --- src/Protocol/Protocol18x.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 60501a5b5..e336dcbec 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -947,11 +947,7 @@ void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); - - // Fake UUID - Pkt.WriteInt64(4053239666997989821); - Pkt.WriteInt64(-5603022497796657139); - + Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID())); Pkt.WriteFPInt(a_Player.GetPosX()); Pkt.WriteFPInt(a_Player.GetPosY()); Pkt.WriteFPInt(a_Player.GetPosZ()); -- cgit v1.2.3 From f94df06b6601f9dcecd383f5d093d225f41d1c65 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 9 Sep 2014 03:02:25 +0200 Subject: Added the player list to the 1.8 protocol. --- src/ClientHandle.cpp | 10 +++-- src/ClientHandle.h | 2 +- src/Entities/Entity.cpp | 2 +- src/Entities/Player.cpp | 4 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 12 ++++-- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol17x.cpp | 13 +++++-- src/Protocol/Protocol17x.h | 2 +- src/Protocol/Protocol18x.cpp | 74 +++++++++++++++++++++++++++++++++---- src/Protocol/Protocol18x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 +- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 6 +-- src/World.h | 2 +- 15 files changed, 108 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f24309159..f97ce26c9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -127,7 +127,7 @@ cClientHandle::~cClientHandle() if (!m_Username.empty() && (World != NULL)) { // Send the Offline PlayerList packet: - World->BroadcastPlayerListItem(*m_Player, false, this); + World->BroadcastPlayerListItem(*m_Player, 4, this); } if (World != NULL) { @@ -366,6 +366,10 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, m_Player->Initialize(*World); m_State = csAuthenticated; + // Send player list items + SendPlayerListItem(*m_Player, 0); + World->SendPlayerList(m_Player); + // Query player team m_Player->UpdateTeam(); @@ -2378,9 +2382,9 @@ void cClientHandle::SendPlayerAbilities() -void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, char a_Action) { - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_Player, a_Action); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 74e89deee..eaa4e90fd 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -156,7 +156,7 @@ public: void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount); void SendPlayerAbilities (void); - void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline); + void SendPlayerListItem (const cPlayer & a_Player, char a_Action); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 9bcdcffeb..fba688847 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -135,7 +135,7 @@ const char * cEntity::GetParentClass(void) const bool cEntity::Initialize(cWorld & a_World) { - if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this)) + if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this) && !IsPlayer()) { return false; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index b0da6965a..a720d8c35 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -266,7 +266,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) cTimer t1; if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { - m_World->SendPlayerList(this); + m_World->BroadcastPlayerListItem(*this, 2); m_LastPlayerListTime = t1.GetNowTime(); } @@ -1172,6 +1172,8 @@ void cPlayer::SetGameMode(eGameMode a_GameMode) SetFlying(false); SetCanFly(false); } + + m_World->BroadcastPlayerListItem(*this, 1); } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 5811e5bff..902c72675 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -94,7 +94,7 @@ public: virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) = 0; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) = 0; + virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) = 0; virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 77939d933..8c4534ff7 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -720,9 +720,15 @@ void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, char a_Action) { cCSLock Lock(m_CSPacket); + if (a_Action == 1) + { + // Ignore gamemode update + return; + } + AString PlayerName(a_Player.GetColor()); PlayerName.append(a_Player.GetName()); if (PlayerName.length() > 14) @@ -733,8 +739,8 @@ void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) WriteByte ((unsigned char)PACKET_PLAYER_LIST_ITEM); WriteString(PlayerName); - WriteBool (a_IsOnline); - WriteShort (a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + WriteBool (a_Action != 4); + WriteShort ((a_Action == 4) ? 0 : a_Player.GetClientHandle()->GetPing()); Flush(); } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 1063777a2..029845b8b 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -65,7 +65,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 162d4da30..b4f96bd88 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -867,14 +867,19 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, char a_Action) { ASSERT(m_State == 3); // In game mode? - + if (a_Action == 1) + { + // Ignore gamemode update + return; + } + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet Pkt.WriteString(a_Player.GetName()); - Pkt.WriteBool(a_IsOnline); - Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + Pkt.WriteBool(a_Action != 4); + Pkt.WriteShort((a_Action == 4) ? 0 : a_Player.GetClientHandle()->GetPing()); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 24fe1cb20..6bb5873d3 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -101,7 +101,7 @@ public: virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index e336dcbec..5f1f97a4a 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -659,7 +659,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4 Pkt.WriteChar((char)a_World.GetDimension()); Pkt.WriteByte(2); // TODO: Difficulty (set to Normal) - Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60)); + Pkt.WriteByte(Server->GetMaxPlayers()); Pkt.WriteString("default"); // Level type - wtf? Pkt.WriteBool(false); // Reduced Debug Info - wtf? } @@ -868,14 +868,74 @@ void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol180::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol180::SendPlayerListItem(const cPlayer & a_Player, char a_Action) { ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteString(a_Player.GetName()); - Pkt.WriteBool(a_IsOnline); - Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0);*/ + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt(a_Action); + Pkt.WriteVarInt(1); + Pkt.WriteUUID(a_Player.GetUUID()); + + switch (a_Action) + { + case 0: + { + // Add Player + Pkt.WriteString(a_Player.GetName()); + + const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); + Pkt.WriteVarInt(Properties.size()); + for (Json::Value::iterator itr = Properties.begin(), end = Properties.end(); itr != end; ++itr) + { + Pkt.WriteString(((Json::Value)*itr).get("name", "").asString()); + Pkt.WriteString(((Json::Value)*itr).get("value", "").asString()); + AString Signature = ((Json::Value)*itr).get("signature", "").asString(); + if (Signature.empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Signature); + } + } + + Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); + Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); + Pkt.WriteBool(false); + break; + } + case 1: + { + // Update GameMode + Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); + break; + } + case 2: + { + // Update Ping + Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); + break; + } + case 3: + { + // Update DisplayName + Pkt.WriteBool(false); + break; + } + case 4: + { + // Remove player + break; + } + default: + { + ASSERT(!"Unhandled player list item action!"); + return; + } + } } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 207af0b44..8e8570b68 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -97,7 +97,7 @@ public: virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c535390cc..56e5b43f3 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -489,10 +489,10 @@ void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_A -void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, char a_Action) { ASSERT(m_Protocol != NULL); - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_Player, a_Action); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 2e8976a9f..4d2bceb68 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -101,7 +101,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/World.cpp b/src/World.cpp index e669f6fa0..0e0846943 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2147,7 +2147,7 @@ void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src -void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude) +void cWorld::BroadcastPlayerListItem(const cPlayer & a_Player, char a_Action, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2157,7 +2157,7 @@ void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, { continue; } - ch->SendPlayerListItem(a_Player, a_IsOnline); + ch->SendPlayerListItem(a_Player, a_Action); } } @@ -2680,7 +2680,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) cClientHandle * ch = (*itr)->GetClientHandle(); if ((ch != NULL) && !ch->IsDestroyed()) { - a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), true); + a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), 0); } } } diff --git a/src/World.h b/src/World.h index 6316c6811..fae784c20 100644 --- a/src/World.h +++ b/src/World.h @@ -237,7 +237,7 @@ public: void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListItem (const cPlayer & a_Player, char a_Action, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); -- cgit v1.2.3 From 1f0b6eeaf3cfff3e6bc27bf5f3a83be60722a3de Mon Sep 17 00:00:00 2001 From: worktycho Date: Tue, 9 Sep 2014 12:18:20 +0100 Subject: Actually set default --- src/World.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index b7045c7f4..fdc0aebad 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3329,6 +3329,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c if ((Falloff > 15) || (Falloff < 0)) { LOGWARNING("Falloff for %s simulator is out of range, assuming default of %d", a_FluidName, IsWater ? 1 : 2); + Falloff = IsWater ? 1 : 2; } if (NoCaseCompare(SimulatorName, "floody") == 0) -- cgit v1.2.3 From acae3c9c657e48d0dc8c4b2965e5b3d69c53b279 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Tue, 9 Sep 2014 16:00:26 +0200 Subject: Moved sound-configs into BlockID.h and fixed/ added loads of sounds --- src/BlockInfo.cpp | 167 ++++++++++++++++++++++++++++++++++++++++ src/BlockInfo.h | 4 + src/Blocks/BlockBigFlower.h | 6 -- src/Blocks/BlockButton.h | 6 -- src/Blocks/BlockCactus.h | 6 -- src/Blocks/BlockCake.h | 5 -- src/Blocks/BlockCarpet.h | 6 -- src/Blocks/BlockChest.h | 6 -- src/Blocks/BlockCloth.h | 5 -- src/Blocks/BlockCommandBlock.h | 5 -- src/Blocks/BlockComparator.h | 6 -- src/Blocks/BlockCrops.h | 6 -- src/Blocks/BlockDirt.h | 6 -- src/Blocks/BlockEnderchest.h | 5 -- src/Blocks/BlockFire.h | 5 -- src/Blocks/BlockFlower.h | 6 -- src/Blocks/BlockGravel.h | 5 -- src/Blocks/BlockHandler.cpp | 9 --- src/Blocks/BlockHandler.h | 3 - src/Blocks/BlockHayBale.h | 6 -- src/Blocks/BlockLadder.h | 6 -- src/Blocks/BlockLeaves.h | 6 -- src/Blocks/BlockLever.h | 6 -- src/Blocks/BlockMelon.h | 6 -- src/Blocks/BlockMushroom.h | 6 -- src/Blocks/BlockMycelium.h | 5 -- src/Blocks/BlockPlanks.h | 6 -- src/Blocks/BlockRedstoneTorch.h | 6 -- src/Blocks/BlockSand.h | 6 -- src/Blocks/BlockSapling.h | 6 -- src/Blocks/BlockSideways.h | 6 -- src/Blocks/BlockSlab.h | 23 ------ src/Blocks/BlockSnow.h | 6 -- src/Blocks/BlockStairs.h | 18 ----- src/Blocks/BlockStems.h | 6 -- src/Blocks/BlockSugarcane.h | 6 -- src/Blocks/BlockTNT.h | 5 -- src/Blocks/BlockTallGrass.h | 6 -- src/Blocks/BlockTorch.h | 6 -- src/Blocks/BlockTripwire.h | 5 -- src/Blocks/BlockTripwireHook.h | 5 -- src/Blocks/BlockVine.h | 6 -- src/Blocks/BlockWallSign.h | 6 -- src/Blocks/BlockWorkbench.h | 6 -- src/ClientHandle.cpp | 2 +- 45 files changed, 172 insertions(+), 272 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index a59229f87..9ac66d35d 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -18,6 +18,7 @@ cBlockInfo::cBlockInfo() , m_IsSolid(true) , m_FullyOccupiesVoxel(false) , m_CanBeTerraformed(false) + , m_PlaceSound("") , m_Handler(NULL) {} @@ -571,6 +572,172 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SOULSAND ].m_CanBeTerraformed = true; a_Info[E_BLOCK_STAINED_CLAY ].m_CanBeTerraformed = true; a_Info[E_BLOCK_STONE ].m_CanBeTerraformed = true; + + + // Block place sounds: + a_Info[E_BLOCK_STONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_GRASS ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_DIRT ].m_PlaceSound = "dig.gravel"; + a_Info[E_BLOCK_COBBLESTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_PLANKS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SAPLING ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_BEDROCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SAND ].m_PlaceSound = "dig.sand"; + a_Info[E_BLOCK_GRAVEL ].m_PlaceSound = "dig.gravel"; + a_Info[E_BLOCK_GOLD_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_IRON_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_COAL_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_LOG ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_LEAVES ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_SPONGE ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_LAPIS_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_LAPIS_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_DISPENSER ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SANDSTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NOTE_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_POWERED_RAIL ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_DETECTOR_RAIL ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_STICKY_PISTON ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_COBWEB ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_TALL_GRASS ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_DEAD_BUSH ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_PISTON ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_PISTON_EXTENSION ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_WOOL ].m_PlaceSound = "dig.cloth"; + a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_DANDELION ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_FLOWER ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_RED_MUSHROOM ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_GOLD_BLOCK ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_IRON_BLOCK ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_STONE_SLAB ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_BRICK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_TNT ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_BOOKCASE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_OBSIDIAN ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_TORCH ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_FIRE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_MOB_SPAWNER ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_WOODEN_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_CHEST ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_DIAMOND_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_DIAMOND_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_CRAFTING_TABLE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_FARMLAND ].m_PlaceSound = "dig.gravel"; + a_Info[E_BLOCK_FURNACE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_LIT_FURNACE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SIGN_POST ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_WOODEN_DOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_LADDER ].m_PlaceSound = "dig.ladder"; + a_Info[E_BLOCK_RAIL ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_WALLSIGN ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_LEVER ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_IRON_DOOR ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_REDSTONE_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_STONE_BUTTON ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SNOW ].m_PlaceSound = "dig.snow"; + a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_SNOW_BLOCK ].m_PlaceSound = "dig.snow"; + a_Info[E_BLOCK_CACTUS ].m_PlaceSound = "dig.cloth"; + a_Info[E_BLOCK_CLAY ].m_PlaceSound = "dig.gravel"; + a_Info[E_BLOCK_SUGARCANE ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_JUKEBOX ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_PUMPKIN ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_NETHERRACK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SOULSAND ].m_PlaceSound = "dig.sand"; + a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_JACK_O_LANTERN ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_CAKE ].m_PlaceSound = "dig.snow"; + a_Info[E_BLOCK_REDSTONE_REPEATER_OFF ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_TRAPDOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SILVERFISH_EGG ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_STONE_BRICKS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_IRON_BARS ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_MELON ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_PUMPKIN_STEM ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_MELON_STEM ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_VINES ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BRICK_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_MYCELIUM ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_LILY_PAD ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_NETHER_BRICK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NETHER_WART ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_BREWING_STAND ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_CAULDRON ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_END_STONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_DRAGON_EGG ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_WOODEN_SLAB ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_COCOA_POD ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_EMERALD_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_ENDER_CHEST ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_TRIPWIRE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_EMERALD_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SPRUCE_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BIRCH_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_JUNGLE_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_COMMAND_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_BEACON ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_COBBLESTONE_WALL ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_FLOWER_POT ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_CARROTS ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_POTATOES ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_HEAD ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "dig.anvil"; + a_Info[E_BLOCK_TRAPPED_CHEST ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_HOPPER ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_QUARTZ_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_QUARTZ_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_DROPPER ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_STAINED_CLAY ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_NEW_LEAVES ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_HAY_BALE ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth"; + a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass"; } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 4c66c095a..567070a7f 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -48,6 +48,9 @@ public: /** Can a finisher change it? */ bool m_CanBeTerraformed; + /** Sound when placing this block */ + AString m_PlaceSound; + // tolua_end /** Associated block handler. */ @@ -64,6 +67,7 @@ public: inline static bool IsSolid (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSolid; } inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; } inline static bool CanBeTerraformed (BLOCKTYPE a_Type) { return Get(a_Type).m_CanBeTerraformed; } + inline static AString GetPlaceSound (BLOCKTYPE a_Type) { return Get(a_Type).m_PlaceSound; } // tolua_end diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 72e552dee..646980634 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -118,12 +118,6 @@ public: } } } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 3b45afff8..8e4f04740 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -57,12 +57,6 @@ public: } - virtual const char * GetStepSound(void) override - { - return m_BlockType == E_BLOCK_WOODEN_BUTTON ? "step.wood" : "step.stone"; - } - - inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace) { switch (a_BlockFace) diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h index ed441517d..910966c43 100644 --- a/src/Blocks/BlockCactus.h +++ b/src/Blocks/BlockCactus.h @@ -69,12 +69,6 @@ public: { a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1); } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } } ; diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index f05f468e5..3a754ce18 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -43,11 +43,6 @@ public: { return true; } - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } } ; diff --git a/src/Blocks/BlockCarpet.h b/src/Blocks/BlockCarpet.h index d1aa52687..4b287c664 100644 --- a/src/Blocks/BlockCarpet.h +++ b/src/Blocks/BlockCarpet.h @@ -22,12 +22,6 @@ public: cBlockHandler(a_BlockType) { } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } virtual bool GetPlacementBlockTypeMeta( diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 28adbed4f..201f2309b 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -106,12 +106,6 @@ public: // Single chest, no further processing needed } - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; diff --git a/src/Blocks/BlockCloth.h b/src/Blocks/BlockCloth.h index 3c1ae7c25..525176725 100644 --- a/src/Blocks/BlockCloth.h +++ b/src/Blocks/BlockCloth.h @@ -15,11 +15,6 @@ public: : cBlockHandler(a_BlockType) { } - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } } ; diff --git a/src/Blocks/BlockCommandBlock.h b/src/Blocks/BlockCommandBlock.h index cf0103765..b66def201 100644 --- a/src/Blocks/BlockCommandBlock.h +++ b/src/Blocks/BlockCommandBlock.h @@ -20,11 +20,6 @@ public: { a_Pickups.push_back(cItem(E_BLOCK_AIR, 8, 0)); } - - virtual const char * GetStepSound(void) override - { - return "step.stone"; - } } ; diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index 6caaaab13..3443fc69e 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -64,12 +64,6 @@ public: a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw()); return true; } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index ae6e490e1..53e996683 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -100,12 +100,6 @@ public: { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND)); } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index d458c6062..23e5a3cde 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -88,12 +88,6 @@ public: } } // for i - repeat twice } - - - virtual const char * GetStepSound(void) override - { - return "step.gravel"; - } } ; diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 4672f1459..0bc67a8f5 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -33,11 +33,6 @@ public: a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); return true; } - - virtual const char * GetStepSound(void) override - { - return "step.stone"; - } static NIBBLETYPE RotationToMetaData(double a_Rotation) { diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index b9f211042..b6d1d95f2 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -50,11 +50,6 @@ public: return true; } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - /** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */ int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0) diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h index 6f64c062b..3eb8a0baa 100644 --- a/src/Blocks/BlockFlower.h +++ b/src/Blocks/BlockFlower.h @@ -28,12 +28,6 @@ public: { return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)); } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockGravel.h b/src/Blocks/BlockGravel.h index e1c9ff390..717bd5f5f 100644 --- a/src/Blocks/BlockGravel.h +++ b/src/Blocks/BlockGravel.h @@ -15,11 +15,6 @@ public: : cBlockHandler(a_BlockType) { } - - virtual const char * GetStepSound(void) override - { - return "step.gravel"; - } } ; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 6767d4de4..34925a252 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -495,15 +495,6 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac -const char * cBlockHandler::GetStepSound() -{ - return "step.stone"; -} - - - - - bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk) { return true; diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index de90ce55b..b3ada279c 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -84,9 +84,6 @@ public: */ virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop = true, bool a_DropVerbatim = false); - /// Returns step sound name of block - virtual const char * GetStepSound(void); - /// Checks if the block can stay at the specified relative coords in the chunk virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); diff --git a/src/Blocks/BlockHayBale.h b/src/Blocks/BlockHayBale.h index 3c6472adb..8150b10d3 100644 --- a/src/Blocks/BlockHayBale.h +++ b/src/Blocks/BlockHayBale.h @@ -15,12 +15,6 @@ public: : cBlockSidewaysHandler(a_BlockType) { } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 284d1d732..ab3f55439 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -111,12 +111,6 @@ public: int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; return LadderCanBePlacedAt(a_ChunkInterface, BlockX, a_RelY, BlockZ, BlockFace); } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index a8aa28a0f..add571675 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -112,12 +112,6 @@ public: DropBlock(a_ChunkInterface, a_WorldInterface, a_PluginInterface, NULL, BlockX, a_RelY, BlockZ); a_ChunkInterface.DigBlock(a_WorldInterface, BlockX, a_RelY, BlockZ); } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 4316fd06b..3b63b396c 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -70,12 +70,6 @@ public: } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta) { switch (a_Meta & 0x7) diff --git a/src/Blocks/BlockMelon.h b/src/Blocks/BlockMelon.h index 60202d66e..22cdb4d29 100644 --- a/src/Blocks/BlockMelon.h +++ b/src/Blocks/BlockMelon.h @@ -22,12 +22,6 @@ public: cFastRandom Random; a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + Random.NextInt(5)), 0)); } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index 135d418d7..7c06fcc74 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -50,12 +50,6 @@ public: } return true; } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockMycelium.h b/src/Blocks/BlockMycelium.h index 2a8ef5fca..628e87181 100644 --- a/src/Blocks/BlockMycelium.h +++ b/src/Blocks/BlockMycelium.h @@ -22,11 +22,6 @@ public: { a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); } - - virtual const char * GetStepSound(void) override - { - return "step.gravel"; - } } ; diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h index 4c5bb4860..3c243ebdc 100644 --- a/src/Blocks/BlockPlanks.h +++ b/src/Blocks/BlockPlanks.h @@ -27,12 +27,6 @@ public: a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); return true; } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockRedstoneTorch.h b/src/Blocks/BlockRedstoneTorch.h index cb897ba3f..8416a415c 100644 --- a/src/Blocks/BlockRedstoneTorch.h +++ b/src/Blocks/BlockRedstoneTorch.h @@ -23,12 +23,6 @@ public: // Always drop the ON torch, meta 0 a_Pickups.push_back(cItem(E_BLOCK_REDSTONE_TORCH_ON, 1, 0)); } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockSand.h b/src/Blocks/BlockSand.h index 3fc271483..48beab138 100644 --- a/src/Blocks/BlockSand.h +++ b/src/Blocks/BlockSand.h @@ -15,12 +15,6 @@ public: : cBlockHandler(a_BlockType) { } - - virtual const char * GetStepSound(void) override - { - return "step.sand"; - } - }; diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h index de28273d5..bec79c6f3 100644 --- a/src/Blocks/BlockSapling.h +++ b/src/Blocks/BlockSapling.h @@ -46,12 +46,6 @@ public: a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta | 0x08); } } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h index f5f10899d..4b1e38d6d 100644 --- a/src/Blocks/BlockSideways.h +++ b/src/Blocks/BlockSideways.h @@ -65,12 +65,6 @@ public: } } } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index e67f0e8b3..0ad30bb2b 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -85,18 +85,6 @@ public: return true; } - - - virtual const char * GetStepSound(void) override - { - switch (m_BlockType) - { - case E_BLOCK_WOODEN_SLAB: return "step.wood"; - case E_BLOCK_STONE_SLAB: return "step.stone"; - } - ASSERT(!"Unhandled slab type!"); - return ""; - } virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override @@ -174,17 +162,6 @@ public: ASSERT(!"Unhandled double slab type!"); return a_BlockType; } - - virtual const char * GetStepSound(void) override - { - switch (m_BlockType) - { - case E_BLOCK_DOUBLE_STONE_SLAB: return "step.stone"; - case E_BLOCK_DOUBLE_WOODEN_SLAB: return "step.wood"; - } - ASSERT(!"Unhandled double slab type!"); - return ""; - } } ; diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h index 977f19a16..7b6094c9f 100644 --- a/src/Blocks/BlockSnow.h +++ b/src/Blocks/BlockSnow.h @@ -87,12 +87,6 @@ public: { return false; } - - - virtual const char * GetStepSound(void) override - { - return "step.cloth"; - } } ; diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index 417969a82..d396204e0 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -55,24 +55,6 @@ public: } - virtual const char * GetStepSound(void) override - { - if ( - (m_BlockType == E_BLOCK_WOODEN_STAIRS) || - (m_BlockType == E_BLOCK_SPRUCE_WOOD_STAIRS) || - (m_BlockType == E_BLOCK_JUNGLE_WOOD_STAIRS) || - (m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) || - (m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) || - (m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS) - ) - { - return "step.wood"; - } - - return "step.stone"; - } - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to zero diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index b726a0901..860c7dd45 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -47,12 +47,6 @@ public: { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND)); } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h index 5902c791b..c832ff218 100644 --- a/src/Blocks/BlockSugarcane.h +++ b/src/Blocks/BlockSugarcane.h @@ -78,12 +78,6 @@ public: { a_Chunk.GetWorld()->GrowSugarcane(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1); } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h index 283a03730..3a573ae67 100644 --- a/src/Blocks/BlockTNT.h +++ b/src/Blocks/BlockTNT.h @@ -16,11 +16,6 @@ public: { } - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } - virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h index 9c008f793..f520414a7 100644 --- a/src/Blocks/BlockTallGrass.h +++ b/src/Blocks/BlockTallGrass.h @@ -53,12 +53,6 @@ public: { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } } ; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index df5574d5d..fa46b37a8 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -184,12 +184,6 @@ public: // Always drop meta = 0 a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/Blocks/BlockTripwire.h b/src/Blocks/BlockTripwire.h index 3ab17bf4a..d03f37537 100644 --- a/src/Blocks/BlockTripwire.h +++ b/src/Blocks/BlockTripwire.h @@ -20,11 +20,6 @@ public: { a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0)); } - - virtual const char * GetStepSound(void) override - { - return ""; - } }; diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h index 4f9d79483..88d389711 100644 --- a/src/Blocks/BlockTripwireHook.h +++ b/src/Blocks/BlockTripwireHook.h @@ -70,11 +70,6 @@ public: return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn)); } - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } }; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 578224c61..b61673cc5 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -159,12 +159,6 @@ public: { return true; } - - - virtual const char * GetStepSound(void) override - { - return "step.grass"; - } virtual bool DoesDropOnUnsuitable(void) override diff --git a/src/Blocks/BlockWallSign.h b/src/Blocks/BlockWallSign.h index 47649379e..0abe9c52c 100644 --- a/src/Blocks/BlockWallSign.h +++ b/src/Blocks/BlockWallSign.h @@ -27,12 +27,6 @@ public: } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - virtual void OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h index 70468369c..699badaf2 100644 --- a/src/Blocks/BlockWorkbench.h +++ b/src/Blocks/BlockWorkbench.h @@ -30,12 +30,6 @@ public: { return true; } - - - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } } ; diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6b31bfa64..a6d7c3066 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1448,7 +1448,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); // Step sound with 0.8f pitch is used as block placement sound - World->BroadcastSoundEffect(NewBlock->GetStepSound(), (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.8f); + World->BroadcastSoundEffect(cBlockInfo::GetPlaceSound(BlockType), (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.8f); cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); } -- cgit v1.2.3 From 6cc4ac0bcaf7100a471b31606d97e9bbcd026722 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Tue, 9 Sep 2014 16:28:08 +0200 Subject: Removed old sound-configuration for doors --- src/Blocks/BlockDoor.cpp | 9 --------- src/Blocks/BlockDoor.h | 1 - 2 files changed, 10 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index e80473cb5..1204debab 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -109,15 +109,6 @@ void cBlockDoorHandler::OnPlacedByPlayer( -const char * cBlockDoorHandler::GetStepSound(void) -{ - return (m_BlockType == E_BLOCK_WOODEN_DOOR) ? "step.wood" : "step.stone"; -} - - - - - NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta) { if (a_Meta & 0x08) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index c86fe829b..69e30d9c8 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -19,7 +19,6 @@ public: virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override; - virtual const char * GetStepSound(void) override; virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; -- cgit v1.2.3 From 71c3369e084d0b9e3b91f9517069e58aaecc15e3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 9 Sep 2014 18:27:31 +0200 Subject: 1.8: Added MultiBlockChange packet. --- src/ClientHandle.cpp | 7 +-- src/Protocol/ChunkDataSerializer.cpp | 45 +++++++------------ src/Protocol/Protocol18x.cpp | 83 ++++++++++++++++++++++++++---------- src/Protocol/Protocol18x.h | 5 +++ 4 files changed, 86 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f97ce26c9..fa2c2124b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -362,13 +362,14 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, // Send experience m_Player->SendExperience(); - - m_Player->Initialize(*World); - m_State = csAuthenticated; // Send player list items SendPlayerListItem(*m_Player, 0); + World->BroadcastPlayerListItem(*m_Player, 0); World->SendPlayerList(m_Player); + + m_Player->Initialize(*World); + m_State = csAuthenticated; // Query player team m_Player->UpdateTeam(); diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index d4574954e..268cf4a9f 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -9,6 +9,7 @@ #include "ChunkDataSerializer.h" #include "zlib/zlib.h" #include "ByteBuffer.h" +#include "Protocol18x.h" @@ -54,7 +55,10 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int break; } } - m_Serializations[a_Version] = data; + if (!data.empty()) + { + m_Serializations[a_Version] = data; + } return m_Serializations[a_Version]; } @@ -219,40 +223,23 @@ void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_Chu Packet.ReadAll(PacketData); Packet.CommitRead(); - cByteBuffer NumberBuffer(20); + cByteBuffer Buffer(20); if (PacketData.size() >= 256) { - AString PostData; - NumberBuffer.WriteVarInt(PacketData.size()); - NumberBuffer.ReadAll(PostData); - NumberBuffer.CommitRead(); - - // Compress the data: - const uLongf CompressedMaxSize = 200000; - char CompressedData[CompressedMaxSize]; - - uLongf CompressedSize = compressBound(PacketData.size()); - // Run-time check that our compile-time guess about CompressedMaxSize was enough: - ASSERT(CompressedSize <= CompressedMaxSize); - compress2((Bytef*)CompressedData, &CompressedSize, (const Bytef*)PacketData.data(), PacketData.size(), Z_DEFAULT_COMPRESSION); - - NumberBuffer.WriteVarInt(CompressedSize + PostData.size()); - NumberBuffer.WriteVarInt(PacketData.size()); - NumberBuffer.ReadAll(PostData); - NumberBuffer.CommitRead(); - - a_Data.clear(); - a_Data.resize(PostData.size() + CompressedSize); - a_Data.append(PostData.data(), PostData.size()); - a_Data.append(CompressedData, CompressedSize); + if (!cProtocol180::CompressPacket(PacketData, a_Data)) + { + ASSERT(!"Packet compression failed."); + a_Data.clear(); + return; + } } else { AString PostData; - NumberBuffer.WriteVarInt(Packet.GetUsedSpace() + 1); - NumberBuffer.WriteVarInt(0); - NumberBuffer.ReadAll(PostData); - NumberBuffer.CommitRead(); + Buffer.WriteVarInt(Packet.GetUsedSpace() + 1); + Buffer.WriteVarInt(0); + Buffer.ReadAll(PostData); + Buffer.CommitRead(); a_Data.clear(); a_Data.resize(PostData.size() + PacketData.size()); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 5f1f97a4a..c7c6402d9 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -200,18 +200,16 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x22); // Multi Block Change packet + cPacketizer Pkt(*this, 0x22); // Multi Block Change packet Pkt.WriteInt(a_ChunkX); Pkt.WriteInt(a_ChunkZ); Pkt.WriteVarInt((UInt32)a_Changes.size()); for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) { - short Coords = itr->y | (itr->z << 8) | (itr->x << 12); + short Coords = (short) (itr->y | (itr->z << 8) | (itr->x << 12)); Pkt.WriteShort(Coords); - - UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15); - Pkt.WriteVarInt(Block); - } // for itr - a_Changes[]*/ + Pkt.WriteVarInt((itr->BlockType & 0xFFF) << 4 | (itr->BlockMeta & 0xF)); + } // for itr - a_Changes[] } @@ -369,9 +367,9 @@ void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x13); // Destroy Entities packet + cPacketizer Pkt(*this, 0x13); // Destroy Entities packet Pkt.WriteVarInt(1); - Pkt.WriteVarInt(a_Entity.GetUniqueID());*/ + Pkt.WriteVarInt(a_Entity.GetUniqueID()); } @@ -437,10 +435,10 @@ void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x04); // Entity Equipment packet + cPacketizer Pkt(*this, 0x04); // Entity Equipment packet Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); Pkt.WriteShort(a_SlotNum); - Pkt.WriteItem(a_Item);*/ + Pkt.WriteItem(a_Item); } @@ -451,9 +449,9 @@ void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x19); // Entity Head Look packet + cPacketizer Pkt(*this, 0x19); // Entity Head Look packet Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID()); - Pkt.WriteByteAngle(a_Entity.GetHeadYaw());*/ + Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); } @@ -464,11 +462,11 @@ void cProtocol180::SendEntityLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x16); // Entity Look packet + cPacketizer Pkt(*this, 0x16); // Entity Look packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + Pkt.WriteBool(true); // TODO: IsOnGround() on entities } @@ -479,10 +477,10 @@ void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteEntityMetadata(a_Entity); - Pkt.WriteByte(0x7f); // The termination byte*/ + Pkt.WriteByte(0x7f); // The termination byte } @@ -506,12 +504,12 @@ void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet + cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_RelX); Pkt.WriteByte(a_RelY); Pkt.WriteByte(a_RelZ); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + Pkt.WriteBool(true); // TODO: IsOnGround() on entities } @@ -522,14 +520,14 @@ void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet + cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_RelX); Pkt.WriteByte(a_RelY); Pkt.WriteByte(a_RelZ); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGround() on entities*/ + Pkt.WriteBool(true); // TODO: IsOnGround() on entities } @@ -1320,14 +1318,14 @@ void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0x18); + cPacketizer Pkt(*this, 0x18); Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteFPInt(a_Entity.GetPosX()); Pkt.WriteFPInt(a_Entity.GetPosY()); Pkt.WriteFPInt(a_Entity.GetPosZ()); Pkt.WriteByteAngle(a_Entity.GetYaw()); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteBool(true); // TODO: IsOnGrond() on entities*/ + Pkt.WriteBool(true); // TODO: IsOnGrond() on entities } @@ -1531,6 +1529,47 @@ void cProtocol180::SendWindowProperty(const cWindow & a_Window, int a_Property, +bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_CompressedData) +{ + // Compress the data: + const uLongf CompressedMaxSize = 200000; + char CompressedData[CompressedMaxSize]; + + uLongf CompressedSize = compressBound(a_Packet.size()); + if (CompressedSize >= CompressedMaxSize) + { + ASSERT(!"Too high packet size."); + return false; + } + + int Status = compress2((Bytef*)CompressedData, &CompressedSize, (const Bytef*)a_Packet.data(), a_Packet.size(), Z_DEFAULT_COMPRESSION); + if (Status != Z_OK) + { + return false; + } + + AString LengthData; + cByteBuffer Buffer(20); + Buffer.WriteVarInt((UInt32)a_Packet.size()); + Buffer.ReadAll(LengthData); + Buffer.CommitRead(); + + Buffer.WriteVarInt(CompressedSize + LengthData.size()); + Buffer.WriteVarInt(a_Packet.size()); + Buffer.ReadAll(LengthData); + Buffer.CommitRead(); + + a_CompressedData.clear(); + a_CompressedData.resize(LengthData.size() + CompressedSize); + a_CompressedData.append(LengthData.data(), LengthData.size()); + a_CompressedData.append(CompressedData, CompressedSize); + return true; +} + + + + + void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 8e8570b68..33e298e48 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -133,6 +133,11 @@ public: virtual AString GetAuthServerID(void) override { return m_AuthServerID; } + /** Compress the packet. a_Packet must be without packet length. + a_Compressed will be set to the compressed packet includes packet length and data length. + If compression fails, the function returns false. */ + static bool CompressPacket(const AString & a_Packet, AString & a_Compressed); + protected: /** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */ -- cgit v1.2.3 From 27edb7f0d04a6f55f2bdd6599f151b3f67d7522f Mon Sep 17 00:00:00 2001 From: Masy98 Date: Tue, 9 Sep 2014 19:37:07 +0200 Subject: Removed old sound-configuration for Trapdoors --- src/Blocks/BlockTrapdoor.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index a6327b5c2..41256ae55 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -16,11 +16,6 @@ public: { } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to zero -- cgit v1.2.3 From a171a6ce937d7cb1814361f5ce2c7d08e34dd185 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Tue, 9 Sep 2014 19:50:35 +0200 Subject: Removed old sound-configuration for Repeaters --- src/Blocks/BlockRedstoneRepeater.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 4b18add12..3e5259c56 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -63,12 +63,6 @@ public: } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - inline static NIBBLETYPE RepeaterRotationToMetaData(double a_Rotation) { a_Rotation += 90 + 45; // So its not aligned with axis -- cgit v1.2.3 From 65e6b1e50ef38f7da695b74349afc825de1ec974 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Tue, 9 Sep 2014 20:10:37 +0200 Subject: Removed old sound-configuration for SignPosts --- src/Blocks/BlockSignPost.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h index d0cc760b0..40e15c253 100644 --- a/src/Blocks/BlockSignPost.h +++ b/src/Blocks/BlockSignPost.h @@ -27,12 +27,6 @@ public: } - virtual const char * GetStepSound(void) override - { - return "step.wood"; - } - - virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { if (a_RelY <= 0) -- cgit v1.2.3 From 27be1799392e89b2b67121ea6febd51c2b9ec4fb Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 10 Sep 2014 16:07:00 +0100 Subject: Added abilty to set build info build info is displayed at startup Fixes #1410 --- src/BuildInfo.h.cmake | 15 +++++++++++++++ src/CMakeLists.txt | 3 +++ src/Root.cpp | 6 ++++++ 3 files changed, 24 insertions(+) create mode 100644 src/BuildInfo.h.cmake (limited to 'src') diff --git a/src/BuildInfo.h.cmake b/src/BuildInfo.h.cmake new file mode 100644 index 000000000..6337dab3e --- /dev/null +++ b/src/BuildInfo.h.cmake @@ -0,0 +1,15 @@ + +#pragma once + +#cmakedefine BUILD_ID + +#ifdef BUILD_ID + +#undef BUILD_ID + +#define BUILD_SERIES_NAME "@BUILD_SERIES_NAME@" +#define BUILD_ID "@BUILD_ID@" +#define BUILD_COMMIT_ID "@BUILD_COMMIT_ID@" +#define BUILD_DATETIME "@BUILD_DATETIME@" +#endif + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d96662a9..9d0e2cede 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,6 +75,7 @@ SET (HDRS BlockInfo.h BlockTracer.h BoundingBox.h + BuildInfo.h.cmake ByteBuffer.h ChatColor.h Chunk.h @@ -140,6 +141,8 @@ include_directories(".") include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/sqlite") include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/SQLiteCpp/include") +configure_file("BuildInfo.h.cmake" "${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.h") + if (NOT MSVC) # Bindings need to reference other folders, so they are done here instead # lib dependencies are not included diff --git a/src/Root.cpp b/src/Root.cpp index 870662f36..86a497a76 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -18,6 +18,7 @@ #include "DeadlockDetect.h" #include "OSSupport/Timer.h" #include "LoggerListeners.h" +#include "BuildInfo.h" #include "inifile/iniFile.h" @@ -111,6 +112,11 @@ void cRoot::Start(void) LOG("--- Started Log ---\n"); + #ifdef BUILD_ID + LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID ); + LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME ); + #endif + cDeadlockDetect dd; m_bStop = false; -- cgit v1.2.3 From 32002694b09ae147e241c7df49a502b82974af9b Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 10 Sep 2014 18:47:59 +0100 Subject: Grammar fixes. --- src/HTTPServer/HTTPServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index c91be677e..0c41b54b2 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -170,8 +170,8 @@ bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_Port // Notify the admin about the HTTPS / HTTP status if (m_Cert.get() == NULL) { - LOGWARNING("WebServer: The server is running in unsecure HTTP mode."); - LOGINFO("Put a valid HTTPS certificate to file 'webadmin/httpscert.crt' and its corresponding private key to 'httpskey.pem' (without any password) to enable HTTPS support"); + LOGWARNING("WebServer: The server is running in unsecured HTTP mode."); + LOGINFO("Put a valid HTTPS certificate in file 'webadmin/httpscert.crt' and its corresponding private key to 'webadmin/httpskey.pem' (without any password) to enable HTTPS support"); } else { -- cgit v1.2.3 From c967633d0ae42f3ffa02d2b31ab723db7ab2c6c8 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:02:15 +0200 Subject: Added 1.8 Blocks and Items --- src/BlockID.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index d835f9518..d6712a588 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -175,12 +175,35 @@ enum ENUM_BLOCK_ID E_BLOCK_NEW_LOG = 162, E_BLOCK_ACACIA_WOOD_STAIRS = 163, E_BLOCK_DARK_OAK_WOOD_STAIRS = 164, + E_BLOCK_SLIME_BLOCK = 165, + E_BLOCK_IRON_TRAPDOOR = 167, + E_BLOCK_PRISMARINE_BLOCK = 168, + E_BLOCK_SEA_LANTERN = 169, E_BLOCK_HAY_BALE = 170, E_BLOCK_CARPET = 171, E_BLOCK_HARDENED_CLAY = 172, E_BLOCK_BLOCK_OF_COAL = 173, E_BLOCK_PACKED_ICE = 174, E_BLOCK_BIG_FLOWER = 175, + E_BLOCK_RED_SANDSTONE = 179, + E_BLOCK_RED_SANDSTONE_STAIRS = 180, + E_BLOCK_NEW_STONE_SLAB = 181, + E_BLOCK_SPRUCE_FENCE_GATE = 182, + E_BLOCK_BIRCH_FENCE_GATE = 183, + E_BLOCK_JUNGLE_FENCE_GATE = 184, + E_BLOCK_DARK_OAK_FENCE_GATE = 185, + E_BLOCK_ACACIA_FENCE_GATE = 186, + E_BLOCK_SPRUCE_FENCE = 187, + E_BLOCK_BIRCH_FENCE = 188, + E_BLOCK_JUNGLE_FENCE = 189, + E_BLOCK_DARK_OAK_FENCE = 190, + E_BLOCK_ACACIA_FENCE = 191, + // I don't know which block has the ID 192, maybe there is no block but we have to wait for mcp + E_BLOCK_SPRUCE_DOOR = 193, + E_BLOCK_BIRCH_DOOR = 194, + E_BLOCK_JUNGLE_DOOR = 195, + E_BLOCK_ACACIA_DOOR = 196, + E_BLOCK_DARK_OAK_DOOR = 197, // Keep these two as the last values, without a number - they will get their correct number assigned automagically by C++ // IsValidBlock() depends on this @@ -356,6 +379,14 @@ enum ENUM_ITEM_ID E_ITEM_NETHER_QUARTZ = 406, E_ITEM_MINECART_WITH_TNT = 407, E_ITEM_MINECART_WITH_HOPPER = 408, + E_ITEM_PRISMARINE_SHARD = 409, + E_ITEM_PRISMARINE_CRYSTALS = 410, + E_ITEM_RAW_RABBIT = 411, + E_ITEM_COOKED_RABBIT = 412, + E_ITEM_RABBIT_STEW = 413, + E_ITEM_RABBITS_FOOD = 414, + E_ITEM_RABBIT_HIDE = 415, + E_ITEM_ARMOR_STAND = 416, E_ITEM_IRON_HORSE_ARMOR = 417, E_ITEM_GOLD_HORSE_ARMOR = 418, E_ITEM_DIAMOND_HORSE_ARMOR = 419, @@ -364,6 +395,12 @@ enum ENUM_ITEM_ID E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422, E_ITEM_RAW_MUTTON = 423, E_ITEM_MUTTON = 424, + E_ITEM_BANNER = 425, + E_ITEM_SPRUCE_DOOR = 427, + E_ITEM_BIRCH_DOOR = 428, + E_ITEM_JUNGLE_DOOR = 429, + E_ITEM_ACACIA_DOOR = 430, + E_ITEM_DARK_OAK_DOOR = 431, // Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++ // IsValidItem() depends on this! -- cgit v1.2.3 From 074dcbf9505fa7ab3fc11efc7efbf919929e7b23 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:07:37 +0200 Subject: Added iron trapdoor, fence gates and doors to the redstone simulator --- src/Simulator/IncrementalRedstoneSimulator.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 7b3a2c2fa..a024a8be7 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -286,8 +286,14 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_SPRUCE_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_BIRCH_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_JUNGLE_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_DARK_OAK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_ACACIA_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_IRON_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TRAPPED_CHEST: HandleTrappedChest(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_ACTIVATOR_RAIL: @@ -298,6 +304,11 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int break; } case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_ACACIA_DOOR: case E_BLOCK_IRON_DOOR: { HandleDoor(dataitr->x, dataitr->y, dataitr->z); -- cgit v1.2.3 From f173cfe4301913ed435086b493c3d2549a3786a7 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:15:06 +0200 Subject: Added new blocks to the BlockHandler --- src/Blocks/BlockHandler.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 34925a252..689874049 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -176,12 +176,16 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) switch (a_BlockType) { // Block handlers, alphabetically sorted: + case E_BLOCK_ACACIA_DOOR: return new cBlockFenceGateHandler (a_BlockType); + case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BEACON: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType); + case E_BLOCK_BIRCH_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_BIRCH_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType); case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); @@ -199,6 +203,8 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_COBBLESTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_COBWEB: return new cBlockCobWebHandler (a_BlockType); case E_BLOCK_CROPS: return new cBlockCropsHandler (a_BlockType); + case E_BLOCK_DARK_OAK_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_DARK_OAK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_DARK_OAK_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_DEAD_BUSH: return new cBlockDeadBushHandler (a_BlockType); case E_BLOCK_DETECTOR_RAIL: return new cBlockRailHandler (a_BlockType); @@ -230,8 +236,11 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType); case E_BLOCK_IRON_DOOR: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_IRON_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_IRON_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); case E_BLOCK_JACK_O_LANTERN: return new cBlockPumpkinHandler (a_BlockType); case E_BLOCK_JUKEBOX: return new cBlockEntityHandler (a_BlockType); + case E_BLOCK_JUNGLE_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_JUNGLE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType); case E_BLOCK_LEVER: return new cBlockLeverHandler (a_BlockType); @@ -251,6 +260,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_NEW_LEAVES: return new cBlockLeavesHandler (a_BlockType); case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType); + case E_BLOCK_NEW_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); case E_BLOCK_NOTE_BLOCK: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler; @@ -262,6 +272,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType); case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_RED_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); @@ -277,6 +288,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType); case E_BLOCK_SIGN_POST: return new cBlockSignPostHandler (a_BlockType); case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); + case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType); -- cgit v1.2.3 From a9b4b60c80f4c23e58adb05622d4a1ff41277d57 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:44:04 +0200 Subject: Added new blocks to the BlockInfo --- src/BlockID.h | 24 ++++++++--------- src/BlockInfo.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/Blocks/BlockHandler.cpp | 1 + 3 files changed, 76 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index d6712a588..e7838da27 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -187,18 +187,18 @@ enum ENUM_BLOCK_ID E_BLOCK_BIG_FLOWER = 175, E_BLOCK_RED_SANDSTONE = 179, E_BLOCK_RED_SANDSTONE_STAIRS = 180, - E_BLOCK_NEW_STONE_SLAB = 181, - E_BLOCK_SPRUCE_FENCE_GATE = 182, - E_BLOCK_BIRCH_FENCE_GATE = 183, - E_BLOCK_JUNGLE_FENCE_GATE = 184, - E_BLOCK_DARK_OAK_FENCE_GATE = 185, - E_BLOCK_ACACIA_FENCE_GATE = 186, - E_BLOCK_SPRUCE_FENCE = 187, - E_BLOCK_BIRCH_FENCE = 188, - E_BLOCK_JUNGLE_FENCE = 189, - E_BLOCK_DARK_OAK_FENCE = 190, - E_BLOCK_ACACIA_FENCE = 191, - // I don't know which block has the ID 192, maybe there is no block but we have to wait for mcp + E_BLOCK_DOUBLE_NEW_STONE_SLAB= 181, + E_BLOCK_NEW_STONE_SLAB = 182, + E_BLOCK_SPRUCE_FENCE_GATE = 183, + E_BLOCK_BIRCH_FENCE_GATE = 184, + E_BLOCK_JUNGLE_FENCE_GATE = 185, + E_BLOCK_DARK_OAK_FENCE_GATE = 186, + E_BLOCK_ACACIA_FENCE_GATE = 187, + E_BLOCK_SPRUCE_FENCE = 188, + E_BLOCK_BIRCH_FENCE = 189, + E_BLOCK_JUNGLE_FENCE = 190, + E_BLOCK_DARK_OAK_FENCE = 191, + E_BLOCK_ACACIA_FENCE = 192, E_BLOCK_SPRUCE_DOOR = 193, E_BLOCK_BIRCH_DOOR = 194, E_BLOCK_JUNGLE_DOOR = 195, diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 9ac66d35d..3586757b9 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -84,11 +84,15 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; + a_Info[E_BLOCK_SEA_LANTERN ].m_LightValue = 15; a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; a_Info[E_BLOCK_TORCH ].m_LightValue = 14; // Spread blocks + a_Info[E_BLOCK_ACACIA_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_ACACIA_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; @@ -96,6 +100,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_BEACON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BED ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BIG_FLOWER ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_BIRCH_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_BIRCH_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BREWING_STAND ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_CACTUS ].m_SpreadLightFalloff = 1; @@ -109,6 +116,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_DANDELION ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_DARK_OAK_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_DARK_OAK_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_DEAD_BUSH ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_DETECTOR_RAIL ].m_SpreadLightFalloff = 1; @@ -132,6 +142,10 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_JUNGLE_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_JUNGLE_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_LADDER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_LEVER ].m_SpreadLightFalloff = 1; @@ -142,6 +156,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NETHER_PORTAL ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_NETHER_WART ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_NEW_STONE_SLAB ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_PISTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_PISTON_EXTENSION ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_SpreadLightFalloff = 1; @@ -158,6 +173,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SAPLING ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_SNOW ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_SPRUCE_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_SPRUCE_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STICKY_PISTON ].m_SpreadLightFalloff = 1; @@ -186,6 +204,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) // Transparent blocks + a_Info[E_BLOCK_ACACIA_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_ACACIA_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_Transparent = true; a_Info[E_BLOCK_AIR ].m_Transparent = true; @@ -193,6 +214,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_BEACON ].m_Transparent = true; a_Info[E_BLOCK_BED ].m_Transparent = true; a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; + a_Info[E_BLOCK_BIRCH_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_BIRCH_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; a_Info[E_BLOCK_BREWING_STAND ].m_Transparent = true; a_Info[E_BLOCK_CACTUS ].m_Transparent = true; @@ -206,6 +230,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_COBWEB ].m_Transparent = true; a_Info[E_BLOCK_CROPS ].m_Transparent = true; a_Info[E_BLOCK_DANDELION ].m_Transparent = true; + a_Info[E_BLOCK_DARK_OAK_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_DARK_OAK_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_Transparent = true; a_Info[E_BLOCK_DEAD_BUSH ].m_Transparent = true; a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; @@ -229,6 +256,10 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_Transparent = true; a_Info[E_BLOCK_IRON_BARS ].m_Transparent = true; a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_Transparent = true; + a_Info[E_BLOCK_JUNGLE_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_JUNGLE_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_JUGNLE_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_LADDER ].m_Transparent = true; a_Info[E_BLOCK_LAVA ].m_Transparent = true; a_Info[E_BLOCK_LEAVES ].m_Transparent = true; @@ -241,6 +272,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NETHER_PORTAL ].m_Transparent = true; a_Info[E_BLOCK_NETHER_WART ].m_Transparent = true; a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; + a_Info[E_BLOCK_NEW_STONE_SLAB ].m_Transparent = true; a_Info[E_BLOCK_PISTON ].m_Transparent = true; a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_Transparent = true; @@ -257,6 +289,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SAPLING ].m_Transparent = true; a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; a_Info[E_BLOCK_SNOW ].m_Transparent = true; + a_Info[E_BLOCK_SPRUCE_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_SPRUCE_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; @@ -388,6 +423,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_DIAMOND_ORE ].m_IsSnowable = true; a_Info[E_BLOCK_DIRT ].m_IsSnowable = true; a_Info[E_BLOCK_DISPENSER ].m_IsSnowable = true; + a_Info[E_BLOCK_DOUBLE_NEW_STONE_SLAB].m_IsSnowable = true; a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_IsSnowable = true; a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_IsSnowable = true; a_Info[E_BLOCK_DROPPER ].m_IsSnowable = true; @@ -424,14 +460,17 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NOTE_BLOCK ].m_IsSnowable = true; a_Info[E_BLOCK_OBSIDIAN ].m_IsSnowable = true; a_Info[E_BLOCK_PLANKS ].m_IsSnowable = true; + a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_IsSnowable = true; a_Info[E_BLOCK_PUMPKIN ].m_IsSnowable = true; a_Info[E_BLOCK_QUARTZ_BLOCK ].m_IsSnowable = true; + a_Info[E_BLOCK_RED_SANDSTONE ].m_IsSnowable = true; a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_IsSnowable = true; a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_IsSnowable = true; a_Info[E_BLOCK_REDSTONE_ORE ].m_IsSnowable = true; a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_IsSnowable = true; a_Info[E_BLOCK_SAND ].m_IsSnowable = true; a_Info[E_BLOCK_SANDSTONE ].m_IsSnowable = true; + a_Info[E_BLOCK_SEA_LANTERN ].m_IsSnowable = true; a_Info[E_BLOCK_SILVERFISH_EGG ].m_IsSnowable = true; a_Info[E_BLOCK_SNOW_BLOCK ].m_IsSnowable = true; a_Info[E_BLOCK_SOULSAND ].m_IsSnowable = true; @@ -537,8 +576,10 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_RED_SANDSTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; @@ -732,12 +773,34 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // I hope it is named slime, it's definetly a new sound type though... + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal"; + a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SEA_LANTERN ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_HAY_BALE ].m_PlaceSound = "dig.grass"; a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth"; a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.glass"; a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_RED_SANDSTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_RED_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NEW_STONE_SLAB ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SPRUCE_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BIRCH_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_JUNGLE_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_DARK_OAK_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_ACACIA_FENCE ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_SPRUCE_DOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_BIRCH_DOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_JUNGLE_DOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_ACACIA_DOOR ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_DARK_OAK_DOOR ].m_PlaceSound = "dig.wood"; } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 689874049..87be27a91 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -211,6 +211,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_DIAMOND_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_DISPENSER: return new cBlockDropSpenserHandler (a_BlockType); + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return new cBlockDropSpenserHandler (a_BlockType); case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockDoubleSlabHandler (a_BlockType); case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockDoubleSlabHandler (a_BlockType); case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType); -- cgit v1.2.3 From c0e86e736025a55222f62b8571969ea3a714c24e Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:47:15 +0200 Subject: Fixed typo --- src/BlockInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 3586757b9..adc112708 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -259,7 +259,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_IRON_TRAPDOOR ].m_Transparent = true; a_Info[E_BLOCK_JUNGLE_DOOR ].m_Transparent = true; a_Info[E_BLOCK_JUNGLE_FENCE ].m_Transparent = true; - a_Info[E_BLOCK_JUGNLE_FENCE_GATE ].m_Transparent = true; + a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_LADDER ].m_Transparent = true; a_Info[E_BLOCK_LAVA ].m_Transparent = true; a_Info[E_BLOCK_LEAVES ].m_Transparent = true; -- cgit v1.2.3 From 214cc0f15d6ba7cafe6d3f1b35f631d6541cdf88 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 10 Sep 2014 21:50:46 +0200 Subject: Added stone slab in BlockSlab.h --- src/Blocks/BlockSlab.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 0ad30bb2b..4c46a39c5 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -96,7 +96,7 @@ public: /// Returns true if the specified blocktype is one of the slabs handled by this handler static bool IsAnySlabType(BLOCKTYPE a_BlockType) { - return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB)); + return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB) || (a_BlockType == E_BLOCK_NEW_STONE_SLAB)); } @@ -119,6 +119,7 @@ public: { case E_BLOCK_STONE_SLAB: return E_BLOCK_DOUBLE_STONE_SLAB; case E_BLOCK_WOODEN_SLAB: return E_BLOCK_DOUBLE_WOODEN_SLAB; + case E_BLOCK_NEW_STONE_SLAB: return E_BLOCK_DOUBLE_NEW_STONE_SLAB; } ASSERT(!"Unhandled slab type!"); return E_BLOCK_AIR; @@ -158,6 +159,7 @@ public: { case E_BLOCK_DOUBLE_STONE_SLAB: return E_BLOCK_STONE_SLAB; case E_BLOCK_DOUBLE_WOODEN_SLAB: return E_BLOCK_WOODEN_SLAB; + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return E_BLOCK_NEW_STONE_SLAB; } ASSERT(!"Unhandled double slab type!"); return a_BlockType; -- cgit v1.2.3 From 9fd5df26d0c9e8c0f99a2a1dbf620f76eaa65be1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 11 Sep 2014 10:28:48 +0200 Subject: Fixed a redstone sim failure with droppers. --- src/Chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 99e48df95..e75acb03b 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2215,7 +2215,7 @@ bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_Blo } } - if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) + if (a_Callback.Item(dynamic_cast(*itr))) // Needs dynamic_cast due to multiple inheritance { return false; } -- cgit v1.2.3 From e34767b265f3a86fff8d99206e7fa024fb7fdf54 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 15:39:37 +0200 Subject: Fixed incorrect handlers --- src/Blocks/BlockHandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 87be27a91..a470e6b21 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -176,8 +176,8 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) switch (a_BlockType) { // Block handlers, alphabetically sorted: - case E_BLOCK_ACACIA_DOOR: return new cBlockFenceGateHandler (a_BlockType); - case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_ACACIA_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); @@ -211,7 +211,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_DIAMOND_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_DISPENSER: return new cBlockDropSpenserHandler (a_BlockType); - case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return new cBlockDropSpenserHandler (a_BlockType); + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return new cBlockDoubleSlabHandler (a_BlockType); case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockDoubleSlabHandler (a_BlockType); case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockDoubleSlabHandler (a_BlockType); case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType); -- cgit v1.2.3 From 5f2e850b0f1650006a8b06578c18ec6bc03d9b37 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 15:48:26 +0200 Subject: Added blocks to the fire simulator --- src/Simulator/FireSimulator.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index cdb5abde2..7ae84af7b 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -179,6 +179,17 @@ bool cFireSimulator::IsFuel(BLOCKTYPE a_BlockType) case E_BLOCK_WOOL: case E_BLOCK_BOOKCASE: case E_BLOCK_FENCE: + case E_BLOCK_SPRUCE_FENCE: + case E_BLOCK_BIRCH_FENCE: + case E_BLOCK_JUNGLE_FENCE: + case E_BLOCK_DARK_OAK_FENCE: + case E_BLOCK_ACACIA_FENCE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_SPRUCE_FENCE_GATE: + case E_BLOCK_BIRCH_FENCE_GATE: + case E_BLOCK_JUNGLE_FENCE_GATE: + case E_BLOCK_DARK_OAK_FENCE_GATE: + case E_BLOCK_ACACIA_FENCE_GATE: case E_BLOCK_TNT: case E_BLOCK_VINES: case E_BLOCK_HAY_BALE: -- cgit v1.2.3 From 8c3cd18cdd175ea1ca06916e557fdf42d6232d71 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 15:57:36 +0200 Subject: Added 1.8 food to the food list --- src/BlockID.h | 2 +- src/Items/ItemFood.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index e7838da27..623b40b13 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -394,7 +394,7 @@ enum ENUM_ITEM_ID E_ITEM_NAME_TAG = 421, E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422, E_ITEM_RAW_MUTTON = 423, - E_ITEM_MUTTON = 424, + E_ITEM_COOKED_MUTTON = 424, E_ITEM_BANNER = 425, E_ITEM_SPRUCE_DOOR = 427, E_ITEM_BIRCH_DOOR = 428, diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 9035344df..886c5e4a3 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -34,7 +34,9 @@ public: // Carrots handled in ItemSeeds case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2); case E_ITEM_COOKED_FISH: return FoodInfo(5, 6); // TODO: Add other fish types + case E_ITEM_COOKED_MUTTON: return FoodInfo(6, 9.6); case E_ITEM_COOKED_PORKCHOP: return FoodInfo(8, 12.8); + case E_ITEM_COOKED_RABBIT: return FoodInfo(5, 6); case E_ITEM_COOKIE: return FoodInfo(2, 0.4); // Golden apple handled in ItemGoldenApple case E_ITEM_GOLDEN_CARROT: return FoodInfo(6, 14.4); @@ -43,16 +45,17 @@ public: case E_ITEM_POISONOUS_POTATO: return FoodInfo(2, 1.2); // Potatoes handled in ItemSeeds case E_ITEM_PUMPKIN_PIE: return FoodInfo(8, 4.8); + case E_ITEM_RABBIT_STEW: return FoodInfo(10, 12); case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8); case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2); case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2); case E_ITEM_RAW_MUTTON: return FoodInfo(2, 1.2); case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8); + case E_ITEM_RAW_RABBIT: return FoodInfo(3, 1.8); case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8); case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2); case E_ITEM_STEAK: return FoodInfo(8, 12.8); - case E_ITEM_MUTTON: return FoodInfo(6, 9.6); } LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType); return FoodInfo(0, 0.f); -- cgit v1.2.3 From 741791ecfc784d5aa0c4e8de11a6f3e99d6cc39d Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 16:07:54 +0200 Subject: Added barrier block --- src/BlockID.h | 1 + src/BlockInfo.cpp | 6 +++++- src/Blocks/BlockPiston.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 623b40b13..5f2ff15cc 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -176,6 +176,7 @@ enum ENUM_BLOCK_ID E_BLOCK_ACACIA_WOOD_STAIRS = 163, E_BLOCK_DARK_OAK_WOOD_STAIRS = 164, E_BLOCK_SLIME_BLOCK = 165, + E_BLOCK_BARRIER = 166, E_BLOCK_IRON_TRAPDOOR = 167, E_BLOCK_PRISMARINE_BLOCK = 168, E_BLOCK_SEA_LANTERN = 169, diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index adc112708..839f1e9f6 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -97,6 +97,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_ANVIL ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_BARRIER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BEACON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BED ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_BIG_FLOWER ].m_SpreadLightFalloff = 1; @@ -211,6 +212,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_Transparent = true; a_Info[E_BLOCK_AIR ].m_Transparent = true; a_Info[E_BLOCK_ANVIL ].m_Transparent = true; + a_Info[E_BLOCK_BARRIER ].m_Transparent = true; a_Info[E_BLOCK_BEACON ].m_Transparent = true; a_Info[E_BLOCK_BED ].m_Transparent = true; a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; @@ -527,7 +529,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) // Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things: - a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BARRIER ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; @@ -572,6 +574,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; @@ -774,6 +777,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // I hope it is named slime, it's definetly a new sound type though... + a_Info[E_BLOCK_BARRIER ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal"; a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_SEA_LANTERN ].m_PlaceSound = "dig.stone"; diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 0bec603e3..f20e8af36 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -94,6 +94,7 @@ private: switch (a_BlockType) { case E_BLOCK_ANVIL: + case E_BLOCK_BARRIER: case E_BLOCK_BEACON: case E_BLOCK_BEDROCK: case E_BLOCK_BREWING_STAND: -- cgit v1.2.3 From b185e7f4e631779ac9b6087dd619ef9ce16b11b0 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 16:11:03 +0200 Subject: Fixed mutton name in ItemHandler --- src/Items/ItemHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 67c945ce4..e9c0026a7 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -217,7 +217,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_GOLDEN_CARROT: case E_ITEM_MELON_SLICE: case E_ITEM_MUSHROOM_SOUP: - case E_ITEM_MUTTON: + case E_ITEM_COOKED_MUTTON: case E_ITEM_POISONOUS_POTATO: case E_ITEM_PUMPKIN_PIE: case E_ITEM_RED_APPLE: -- cgit v1.2.3 From a01994389dea9273916d983891815563c9433e4e Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 16:24:16 +0200 Subject: Fixed mutton name in Sheep.cpp --- src/Items/ItemHandler.cpp | 12 ++++++++++-- src/Mobs/Sheep.cpp | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index e9c0026a7..df8bb6bfa 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -191,6 +191,11 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) return new cItemSeedsHandler(a_ItemType); } + case E_ITEM_ACACIA_DOOR: + case E_ITEM_BIRCH_DOOR: + case E_ITEM_DARK_OAK_DOOR: + case E_ITEM_JUNGLE_DOOR: + case E_ITEM_SPRUCE_DOOR: case E_ITEM_IRON_DOOR: case E_ITEM_WOODEN_DOOR: { @@ -212,20 +217,23 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_BREAD: case E_ITEM_COOKED_CHICKEN: case E_ITEM_COOKED_FISH: + case E_ITEM_COOKED_MUTTON: case E_ITEM_COOKED_PORKCHOP: + case E_ITEM_COOKED_RABBIT: case E_ITEM_COOKIE: case E_ITEM_GOLDEN_CARROT: case E_ITEM_MELON_SLICE: case E_ITEM_MUSHROOM_SOUP: - case E_ITEM_COOKED_MUTTON: case E_ITEM_POISONOUS_POTATO: case E_ITEM_PUMPKIN_PIE: - case E_ITEM_RED_APPLE: + case E_ITEM_RABBIT_STEW: case E_ITEM_RAW_BEEF: case E_ITEM_RAW_CHICKEN: case E_ITEM_RAW_FISH: case E_ITEM_RAW_MUTTON: case E_ITEM_RAW_PORKCHOP: + case E_ITEM_RAW_RABBIT: + case E_ITEM_RED_APPLE: case E_ITEM_ROTTEN_FLESH: case E_ITEM_SPIDER_EYE: case E_ITEM_STEAK: diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 1a82115d2..1122c9809 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -45,7 +45,7 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } - AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_MUTTON : E_ITEM_RAW_MUTTON); + AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_COOKED_MUTTON : E_ITEM_RAW_MUTTON); } -- cgit v1.2.3 From d4641576c0d4731fc771705f9642996aa92a3656 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Thu, 11 Sep 2014 16:33:52 +0200 Subject: Added new doors in ItemDoor.h --- src/Items/ItemDoor.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h index c1b439024..402cef6c6 100644 --- a/src/Items/ItemDoor.h +++ b/src/Items/ItemDoor.h @@ -30,7 +30,21 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - a_BlockType = (m_ItemType == E_ITEM_WOODEN_DOOR) ? E_BLOCK_WOODEN_DOOR : E_BLOCK_IRON_DOOR; + switch (m_ItemType) { + case E_ITEM_WOODEN_DOOR: a_BlockType = E_BLOCK_WOODEN_DOOR; break; + case E_ITEM_IRON_DOOR: a_BlockType = E_BLOCK_IRON_DOOR; break; + case E_ITEM_SPRUCE_DOOR: a_BlockType = E_BLOCK_SPRUCE_DOOR; break; + case E_ITEM_BIRCH_DOOR: a_BlockType = E_BLOCK_BIRCH_DOOR; break; + case E_ITEM_JUNGLE_DOOR: a_BlockType = E_BLOCK_JUNGLE_DOOR; break; + case E_ITEM_DARK_OAK_DOOR: a_BlockType = E_BLOCK_DARK_OAK_DOOR; break; + case E_ITEM_ACACIA_DOOR: a_BlockType = E_BLOCK_ACACIA_DOOR; break; + default: + { + ASSERT(!"Unhandled door type"); + return false; + } + } + cChunkInterface ChunkInterface(a_World->GetChunkMap()); bool Meta = BlockHandler(a_BlockType)->GetPlacementBlockTypeMeta( ChunkInterface, a_Player, -- cgit v1.2.3 From 3bd3ac2200392542b111d2bcd2951bd342edf721 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 11 Sep 2014 17:03:09 +0200 Subject: 1.8: Added ParticleEffect packet. --- src/Chunk.cpp | 4 +- src/Chunk.h | 2 +- src/ChunkMap.cpp | 4 +- src/ChunkMap.h | 2 +- src/ClientHandle.cpp | 4 +- src/ClientHandle.h | 2 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 2 +- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol15x.cpp | 4 +- src/Protocol/Protocol15x.h | 2 +- src/Protocol/Protocol17x.cpp | 4 +- src/Protocol/Protocol17x.h | 2 +- src/Protocol/Protocol18x.cpp | 100 +++++++++++++++++++++++++++++++----- src/Protocol/Protocol18x.h | 5 +- src/Protocol/ProtocolRecognizer.cpp | 4 +- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 4 +- src/World.h | 2 +- 19 files changed, 115 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 99e48df95..79602e64e 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -3043,7 +3043,7 @@ void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation -void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude) +void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) { for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) { @@ -3051,7 +3051,7 @@ void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src { continue; } - (*itr)->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount); + (*itr)->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount); } // for itr - LoadedByClient[] } diff --git a/src/Chunk.h b/src/Chunk.h index f282694c2..e88e72bdc 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -326,7 +326,7 @@ public: void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 9c105c5af..e03c9b86c 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -617,7 +617,7 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat -void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude) +void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; @@ -629,7 +629,7 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_ return; } // It's perfectly legal to broadcast packets even to invalid chunks! - Chunk->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount, a_Exclude); + Chunk->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount, a_Exclude); } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 7354536d4..dcfd1e336 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -87,7 +87,7 @@ public: void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); - void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); + void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index fa2c2124b..3b32b06b9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2339,9 +2339,9 @@ void cClientHandle::SendMapInfo(int a_ID, unsigned int a_Scale) -void cClientHandle::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cClientHandle::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { - m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount); + m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index eaa4e90fd..7c5597b8b 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -154,7 +154,7 @@ public: void SendPaintingSpawn (const cPainting & a_Painting); void SendPickupSpawn (const cPickup & a_Pickup); void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export - void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount); + void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); void SendPlayerAbilities (void); void SendPlayerListItem (const cPlayer & a_Player, char a_Action); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 902c72675..2b41b809c 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -93,7 +93,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0; virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; - virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) = 0; + virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) = 0; virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 8c4534ff7..1d6049097 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -701,7 +701,7 @@ void cProtocol125::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio -void cProtocol125::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocol125::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { // Not supported by this protocol version } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 029845b8b..262e1818d 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -60,7 +60,7 @@ public: virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message diff --git a/src/Protocol/Protocol15x.cpp b/src/Protocol/Protocol15x.cpp index 2b1f01b08..089296fdf 100644 --- a/src/Protocol/Protocol15x.cpp +++ b/src/Protocol/Protocol15x.cpp @@ -80,7 +80,7 @@ void cProtocol150::SendWindowOpen(const cWindow & a_Window) -void cProtocol150::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocol150::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_PARTICLE_EFFECT); @@ -92,7 +92,7 @@ void cProtocol150::SendParticleEffect(const AString & a_ParticleName, float a_Sr WriteFloat(a_OffsetY); WriteFloat(a_OffsetZ); WriteFloat(a_ParticleData); - WriteInt(a_ParticleAmmount); + WriteInt(a_ParticleAmount); Flush(); } diff --git a/src/Protocol/Protocol15x.h b/src/Protocol/Protocol15x.h index 0d171a67c..968d5ebcf 100644 --- a/src/Protocol/Protocol15x.h +++ b/src/Protocol/Protocol15x.h @@ -29,7 +29,7 @@ public: cProtocol150(cClientHandle * a_Client); virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index b4f96bd88..d83e86ece 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -847,7 +847,7 @@ void cProtocol172::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio -void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { ASSERT(m_State == 3); // In game mode? @@ -860,7 +860,7 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr Pkt.WriteFloat(a_OffsetY); Pkt.WriteFloat(a_OffsetZ); Pkt.WriteFloat(a_ParticleData); - Pkt.WriteInt(a_ParticleAmmount); + Pkt.WriteInt(a_ParticleAmount); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 6bb5873d3..60088a1b8 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -98,7 +98,7 @@ public: virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index c7c6402d9..2ea83351e 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -779,7 +779,7 @@ void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) { ASSERT(m_State == 3); // In game mode? - /*{ + { cPacketizer Pkt(*this, 0x0e); // Spawn Object packet Pkt.WriteVarInt(a_Pickup.GetUniqueID()); Pkt.WriteByte(2); // Type = Pickup @@ -797,7 +797,7 @@ void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) Pkt.WriteByte((0x05 << 5) | 10); // Slot type + index 10 Pkt.WriteItem(a_Pickup.GetItem()); Pkt.WriteByte(0x7f); // End of metadata - }*/ + } } @@ -846,12 +846,14 @@ void cProtocol180::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio -void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x2A); - Pkt.WriteString(a_ParticleName); + int ParticleID = GetParticleID(a_ParticleName); + + cPacketizer Pkt(*this, 0x2A); + Pkt.WriteInt(ParticleID); + Pkt.WriteBool(false); Pkt.WriteFloat(a_SrcX); Pkt.WriteFloat(a_SrcY); Pkt.WriteFloat(a_SrcZ); @@ -859,7 +861,7 @@ void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_Sr Pkt.WriteFloat(a_OffsetY); Pkt.WriteFloat(a_OffsetZ); Pkt.WriteFloat(a_ParticleData); - Pkt.WriteInt(a_ParticleAmmount);*/ + Pkt.WriteInt(a_ParticleAmount); } @@ -1230,7 +1232,7 @@ void cProtocol180::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, { ASSERT(m_State == 3); // In game mode? - /*cPacketizer Pkt(*this, 0xe); // Spawn Object packet + cPacketizer Pkt(*this, 0xe); // Spawn Object packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_ObjectType); Pkt.WriteFPInt(a_Entity.GetPosX()); @@ -1244,7 +1246,7 @@ void cProtocol180::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400)); Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400)); Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400)); - }*/ + } } @@ -1570,6 +1572,71 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress +int cProtocol180::GetParticleID(const AString & a_ParticleName) +{ + static bool IsInitialized = false; + static std::map ParticleMap; + if (!IsInitialized) + { + // Initialize the ParticleMap: + ParticleMap["explode"] = 0; + ParticleMap["largeexplode"] = 1; + ParticleMap["hugeexplosion"] = 2; + ParticleMap["fireworksspark"] = 3; + ParticleMap["bubble"] = 4; + ParticleMap["splash"] = 5; + ParticleMap["wake"] = 6; + ParticleMap["suspended"] = 7; + ParticleMap["depthsuspend"] = 8; + ParticleMap["crit"] = 9; + ParticleMap["magiccrit"] = 10; + ParticleMap["smoke"] = 11; + ParticleMap["largesmoke"] = 12; + ParticleMap["spell"] = 13; + ParticleMap["instantspell"] = 14; + ParticleMap["mobspell"] = 15; + ParticleMap["mobspellambient"] = 16; + ParticleMap["witchmagic"] = 17; + ParticleMap["dripwater"] = 18; + ParticleMap["driplava"] = 19; + ParticleMap["angryvillager"] = 20; + ParticleMap["happyVillager"] = 21; + ParticleMap["townaura"] = 22; + ParticleMap["note"] = 23; + ParticleMap["portal"] = 24; + ParticleMap["enchantmenttable"] = 25; + ParticleMap["flame"] = 26; + ParticleMap["lava"] = 27; + ParticleMap["footstep"] = 28; + ParticleMap["cloud"] = 29; + ParticleMap["reddust"] = 30; + ParticleMap["snowballpoof"] = 31; + ParticleMap["snowshovel"] = 32; + ParticleMap["slime"] = 33; + ParticleMap["heart"] = 34; + ParticleMap["barrier"] = 35; + ParticleMap["iconcrack"] = 36; + ParticleMap["blockcrack"] = 37; + ParticleMap["blockdust"] = 38; + ParticleMap["droplet"] = 39; + ParticleMap["take"] = 40; + ParticleMap["mobappearance"] = 41; + } + + AString ParticleName = StrToLower(a_ParticleName); + if (ParticleMap.find(ParticleName) == ParticleMap.end()) + { + LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); + return 0; + } + + return ParticleMap[ParticleName]; +} + + + + + void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: @@ -2685,13 +2752,20 @@ void cProtocol180::cPacketizer::WriteUUID(const AString & a_UUID) { AString UUID_1 = a_UUID.substr(0, a_UUID.length() / 2); AString UUID_2 = a_UUID.substr(a_UUID.length() / 2); - - UInt64 Value_1, Value_2; + + Int64 Value_1, Value_2; sscanf(UUID_1.c_str(), "%llx", &Value_1); sscanf(UUID_2.c_str(), "%llx", &Value_2); - WriteInt64((Int64)Value_1); - WriteInt64((Int64)Value_2); + AString SValue_1, SValue_2; + Printf(SValue_1, "%lld", Value_1); + Printf(SValue_2, "%lld", Value_2); + + StringToInteger(SValue_1.c_str(), Value_1); + StringToInteger(SValue_2.c_str(), Value_2); + + WriteInt64(Value_1); + WriteInt64(Value_2); } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 33e298e48..2b3063556 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -96,7 +96,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; @@ -138,6 +138,9 @@ public: If compression fails, the function returns false. */ static bool CompressPacket(const AString & a_Packet, AString & a_Compressed); + /** The 1.8 protocol use a particle id instead of a string. This function converts the name to the id. If the name is incorrect, it returns 0. */ + static int GetParticleID(const AString & a_ParticleName); + protected: /** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */ diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 56e5b43f3..cf63583db 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -441,10 +441,10 @@ void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale) -void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) +void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { ASSERT(m_Protocol != NULL); - m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount); + m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 4d2bceb68..f73b0b92a 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -96,7 +96,7 @@ public: virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; diff --git a/src/World.cpp b/src/World.cpp index 0e0846943..351dded24 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2138,9 +2138,9 @@ void cWorld::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation -void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude) +void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) { - m_ChunkMap->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount, a_Exclude); + m_ChunkMap->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount, a_Exclude); } diff --git a/src/World.h b/src/World.h index fae784c20..2c363c0af 100644 --- a/src/World.h +++ b/src/World.h @@ -236,7 +236,7 @@ public: void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastPlayerListItem (const cPlayer & a_Player, char a_Action, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); -- cgit v1.2.3 From 0b044e1c83a62c266afaf0852ccbd5e7b01cec5e Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 11 Sep 2014 17:48:21 +0100 Subject: Possibly decoupled IncrementalRedstoneSimulator from the rest of the server THis wil hopefully allow for unit testing --- src/BlockEntities/CommandBlockEntity.h | 7 +- src/BlockEntities/RedstonePoweredEntity.h | 2 +- src/Blocks/GetHandlerCompileTimeTemplate.h | 54 + src/Chunk.cpp | 6 +- src/Chunk.h | 18 +- src/Simulator/CMakeLists.txt | 1 - src/Simulator/FireSimulator.h | 2 +- src/Simulator/FluidSimulator.h | 7 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 2231 +----------------------- src/Simulator/IncrementalRedstoneSimulator.h | 28 +- src/Simulator/IncrementalRedstoneSimulator.inc | 2208 +++++++++++++++++++++++ src/Simulator/NoopRedstoneSimulator.h | 4 +- src/Simulator/RedstoneSimulator.cpp | 19 - src/Simulator/RedstoneSimulator.h | 11 +- src/Simulator/SandSimulator.h | 9 +- src/Simulator/Simulator.cpp | 50 +- src/Simulator/Simulator.h | 17 +- src/Simulator/Simulator.inc | 49 + src/Simulator/SimulatorManager.cpp | 2 +- src/Simulator/SimulatorManager.h | 4 +- src/World.cpp | 6 +- src/World.h | 7 +- 22 files changed, 2403 insertions(+), 2339 deletions(-) create mode 100644 src/Blocks/GetHandlerCompileTimeTemplate.h create mode 100644 src/Simulator/IncrementalRedstoneSimulator.inc delete mode 100644 src/Simulator/RedstoneSimulator.cpp create mode 100644 src/Simulator/Simulator.inc (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index d02bf7d7b..22cd44322 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -10,7 +10,7 @@ #pragma once #include "BlockEntity.h" - +#include "RedstonePoweredEntity.h" @@ -27,7 +27,8 @@ namespace Json // tolua_begin class cCommandBlockEntity : - public cBlockEntity + public cBlockEntity, + public cRedstonePoweredEntity { typedef cBlockEntity super; @@ -52,7 +53,7 @@ public: // tolua_begin /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate - void SetRedstonePower(bool a_IsPowered); + virtual void SetRedstonePower(bool a_IsPowered) override; /// Sets the command block to execute a command in the next tick void Activate(void); diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h index f11df4fc4..eac4e35d4 100644 --- a/src/BlockEntities/RedstonePoweredEntity.h +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -6,7 +6,7 @@ class cRedstonePoweredEntity { public: - virtual ~cRedstonePoweredEntity() {}; + virtual ~cRedstonePoweredEntity() {} /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate virtual void SetRedstonePower(bool a_IsPowered) = 0; diff --git a/src/Blocks/GetHandlerCompileTimeTemplate.h b/src/Blocks/GetHandlerCompileTimeTemplate.h new file mode 100644 index 000000000..658497bf2 --- /dev/null +++ b/src/Blocks/GetHandlerCompileTimeTemplate.h @@ -0,0 +1,54 @@ + +#pragma once + +class cBlockTorchHandler; +class cBlockLeverHandler; +class cBlockButtonHandler; +class cBlockTripwireHookHandler; +class cBlockDoorHandler; +class cBlockPistonHandler; + +template +class GetHandlerCompileTime; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockTorchHandler type; +}; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockLeverHandler type; +}; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockButtonHandler type; +}; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockTripwireHookHandler type; +}; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockDoorHandler type; +}; + +template<> +class GetHandlerCompileTime +{ +public: + typedef cBlockPistonHandler type; +}; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 99e48df95..46520eb56 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1366,9 +1366,9 @@ void cChunk::CreateBlockEntities(void) void cChunk::WakeUpSimulators(void) { - cSimulator * WaterSimulator = m_World->GetWaterSimulator(); - cSimulator * LavaSimulator = m_World->GetLavaSimulator(); - cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator(); + cSimulator * WaterSimulator = m_World->GetWaterSimulator(); + cSimulator * LavaSimulator = m_World->GetLavaSimulator(); + cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator(); int BaseX = m_PosX * cChunkDef::Width; int BaseZ = m_PosZ * cChunkDef::Width; for (int x = 0; x < Width; x++) diff --git a/src/Chunk.h b/src/Chunk.h index f282694c2..9a0e96513 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -9,6 +9,8 @@ #include "Simulator/SandSimulator.h" #include "Simulator/IncrementalRedstoneSimulator.h" +#include "Blocks/GetHandlerCompileTimeTemplate.h" + @@ -416,10 +418,10 @@ public: cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; } cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; } - cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; } - cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; } - cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; } - cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; } + cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; } + cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; } + cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; } + cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; } bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; } void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; } @@ -506,10 +508,10 @@ private: cRedstoneSimulatorChunkData m_RedstoneSimulatorData; cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData; - cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList; - cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList; - cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList; - cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList; + cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList; + cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList; + cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList; + cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList; /** Indicates if simulate-once blocks should be updated by the redstone simulator */ bool m_IsRedstoneDirty; diff --git a/src/Simulator/CMakeLists.txt b/src/Simulator/CMakeLists.txt index 521b145b6..5aa406717 100644 --- a/src/Simulator/CMakeLists.txt +++ b/src/Simulator/CMakeLists.txt @@ -10,7 +10,6 @@ SET (SRCS FloodyFluidSimulator.cpp FluidSimulator.cpp IncrementalRedstoneSimulator.cpp - RedstoneSimulator.cpp SandSimulator.cpp Simulator.cpp SimulatorManager.cpp diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h index 9ccc3ef4f..f76dbe342 100644 --- a/src/Simulator/FireSimulator.h +++ b/src/Simulator/FireSimulator.h @@ -16,7 +16,7 @@ it progresses to the next step (blockmeta++). This value is updated if a neighbo The simulator reads its parameters from the ini file given to the constructor. */ class cFireSimulator : - public cSimulator + public cSimulator { public: cFireSimulator(cWorld & a_World, cIniFile & a_IniFile); diff --git a/src/Simulator/FluidSimulator.h b/src/Simulator/FluidSimulator.h index 672b740a2..0877a7bf1 100644 --- a/src/Simulator/FluidSimulator.h +++ b/src/Simulator/FluidSimulator.h @@ -4,7 +4,8 @@ #include "Simulator.h" - +class cChunk; +class cWorld; enum Direction @@ -36,9 +37,9 @@ public: class cFluidSimulator : - public cSimulator + public cSimulator { - typedef cSimulator super; + typedef cSimulator super; public: cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 7b3a2c2fa..515d72457 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1,2216 +1,23 @@ -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "IncrementalRedstoneSimulator.h" -#include "BoundingBox.h" -#include "../BlockEntities/RedstonePoweredEntity.h" -#include "../BlockEntities/ChestEntity.h" -#include "../BlockEntities/CommandBlockEntity.h" -#include "../Entities/Pickup.h" -#include "../Blocks/BlockTorch.h" -#include "../Blocks/BlockDoor.h" -#include "../Blocks/BlockButton.h" -#include "../Blocks/BlockLever.h" -#include "../Blocks/BlockPiston.h" -#include "../Blocks/BlockTripwireHook.h" - - - - - -cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) : - super(a_World), - m_RedstoneSimulatorChunkData(), - m_PoweredBlocks(), - m_LinkedPoweredBlocks(), - m_SimulatedPlayerToggleableBlocks(), - m_RepeatersDelayList(), - m_Chunk() -{ -} - - - - - -cIncrementalRedstoneSimulator::~cIncrementalRedstoneSimulator() -{ -} - - - - - -void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk, cChunk * a_OtherChunk) -{ - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - else if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height)) - { - return; - } - - // We may be called with coordinates in a chunk that is not the first chunk parameter - // In that case, the actual chunk (which the coordinates are in), will be passed as the second parameter - // Use that Chunk pointer to get a relative position - - int RelX = 0; - int RelZ = 0; - BLOCKTYPE Block; - NIBBLETYPE Meta; - - if (a_OtherChunk != NULL) - { - RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width; - RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width; - a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); - - // If a_OtherChunk is passed (not NULL), it is the chunk that had a block change, and a_Chunk will be the neighbouring chunk of that block - // Because said neighbouring chunk does not know of this change but still needs to update its redstone, we set it to dirty - a_Chunk->SetIsRedstoneDirty(true); - } - else - { - RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); - } - - // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid - // Checking only when a block is changed, as opposed to every tick, also improves performance - - PoweredBlocksList * PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList(); - for (PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end();) - { - if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - ++itr; - continue; - } - - if (!IsPotentialSource(Block)) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = PoweredBlocks->erase(itr); - continue; - } - else if ( - // Changeable sources - ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || - ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || - ((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) || - (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || - ((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0)) - ) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = PoweredBlocks->erase(itr); - continue; - } - ++itr; - } - - LinkedBlocksList * LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); - // We loop through all values (insteading of breaking out at the first) to make sure everything is gone, as there can be multiple SourceBlock entries for one AddBlock coordinate - for (LinkedBlocksList::iterator itr = LinkedPoweredBlocks->begin(); itr != LinkedPoweredBlocks->end();) - { - if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - if (!IsPotentialSource(Block)) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); - continue; - } - else if ( - // Things that can send power through a block but which depends on meta - ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || - ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || - (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) - ) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); - continue; - } - } - else if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - if (!IsViableMiddleBlock(Block)) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); - continue; - } - } - ++itr; - } - - SimulatedPlayerToggleableList * SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); - for (SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks->begin(); itr != SimulatedPlayerToggleableBlocks->end(); ++itr) - { - if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) - { - continue; - } - - if (!IsAllowedBlock(Block)) - { - LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z); - SimulatedPlayerToggleableBlocks->erase(itr); - break; - } - } - - RepeatersDelayList * RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); - for (RepeatersDelayList::iterator itr = RepeatersDelayList->begin(); itr != RepeatersDelayList->end(); ++itr) - { - if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) - { - continue; - } - - if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF)) - { - RepeatersDelayList->erase(itr); - break; - } - } - - if (a_OtherChunk != NULL) - { - // DO NOT touch our chunk's data structure if we are being called with coordinates from another chunk - this one caused me massive grief :P - return; - } - - cRedstoneSimulatorChunkData * RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData(); - for (cRedstoneSimulatorChunkData::iterator itr = RedstoneSimulatorChunkData->begin(); itr != RedstoneSimulatorChunkData->end(); ++itr) - { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block - { - if (!IsAllowedBlock(Block)) - { - itr->DataTwo = true; // The new blocktype is not redstone; it must be queued to be removed from this list - } - else - { - itr->DataTwo = false; - itr->Data = Block; // Update block information - } - return; - } - } - - if (!IsAllowedBlock(Block)) - { - return; - } - - for (cRedstoneSimulatorChunkData::iterator itr = a_Chunk->GetRedstoneSimulatorQueuedData()->begin(); itr != a_Chunk->GetRedstoneSimulatorQueuedData()->end(); ++itr) - { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) - { - // Can't have duplicates in here either, in case something adds the block again before the structure can written to the main chunk data - return; - } - } - a_Chunk->GetRedstoneSimulatorQueuedData()->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false)); -} - - - - - -void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - m_RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData(); - if (m_RedstoneSimulatorChunkData->empty() && a_Chunk->GetRedstoneSimulatorQueuedData()->empty()) - { - return; - } - - m_RedstoneSimulatorChunkData->insert(m_RedstoneSimulatorChunkData->end(), a_Chunk->GetRedstoneSimulatorQueuedData()->begin(), a_Chunk->GetRedstoneSimulatorQueuedData()->end()); - a_Chunk->GetRedstoneSimulatorQueuedData()->clear(); - - m_PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList(); - m_RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); - m_SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); - m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); - m_Chunk = a_Chunk; - bool ShouldUpdateSimulateOnceBlocks = false; - - if (a_Chunk->IsRedstoneDirty()) - { - // Simulate the majority of devices only if something (blockwise or power-wise) has changed - // Make sure to allow the chunk to resimulate after the initial run if there was a power change (ShouldUpdateSimulateOnceBlocks helps to do this) - a_Chunk->SetIsRedstoneDirty(false); - ShouldUpdateSimulateOnceBlocks = true; - } - - HandleRedstoneRepeaterDelays(); - - for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();) - { - if (dataitr->DataTwo) - { - dataitr = m_RedstoneSimulatorChunkData->erase(dataitr); - continue; - } - - switch (dataitr->Data) - { - case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break; - - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - { - HandlePressurePlate(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - default: break; - } - - if (ShouldUpdateSimulateOnceBlocks) - { - switch (dataitr->Data) - { - case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_TRAPPED_CHEST: HandleTrappedChest(dataitr->x, dataitr->y, dataitr->z); break; - - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_POWERED_RAIL: - { - HandleRail(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - { - HandleDoor(dataitr->x, dataitr->y, dataitr->z); - break; - } - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - { - HandleRedstoneLamp(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: - { - HandleDropSpenser(dataitr->x, dataitr->y, dataitr->z); - break; - } - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - HandlePiston(dataitr->x, dataitr->y, dataitr->z); - break; - } - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - { - HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - { - HandleRedstoneTorch(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_WOODEN_BUTTON: - { - HandleRedstoneButton(dataitr->x, dataitr->y, dataitr->z); - break; - } - default: break; - } - } - ++dataitr; - } -} - - - - -void cIncrementalRedstoneSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if (AreCoordsOnChunkBoundary(a_BlockX, a_BlockY, a_BlockZ)) - { - // On a chunk boundary, alert all four sides (i.e. at least one neighbouring chunk) - AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); - - // Pass the original coordinates, because when adding things to our simulator lists, we get the chunk that they are in, and therefore any updates need to preseve their position - // RedstoneAddBlock to pass both the neighbouring chunk and the chunk which the coordinates are in and +- 2 in GetNeighbour() to accomodate for LinkedPowered blocks being 2 away from chunk boundaries - RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 2, a_BlockZ), a_Chunk); - RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 2, a_BlockZ), a_Chunk); - RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 2), a_Chunk); - RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 2), a_Chunk); - - return; - } - - // Not on boundary, just alert this chunk for speed - AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) -{ - static const struct // Define which directions the torch can power - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - { 0, 1, 0}, - } ; - - if (a_MyState == E_BLOCK_REDSTONE_TORCH_ON) - { - // Check if the block the torch is on is powered - int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ; - AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on - - cChunk * Neighbour = m_Chunk->GetRelNeighborChunk(X, Z); - if ((Neighbour == NULL) || !Neighbour->IsValid()) - { - return; - } - - if (AreCoordsDirectlyPowered(X, Y, Z, Neighbour)) - { - // There was a match, torch goes off - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); - return; - } - - // Torch still on, make all 4(X, Z) + 1(Y) sides powered - for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - BLOCKTYPE Type = 0; - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type)) - { - continue; - } - if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last) - { - if ( - IsMechanism(Type) && // Is it a mechanism? Not block/other torch etc. - (!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on - ) - { - SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - } - } - else - { - // Top side, power whatever is there, including blocks - SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - // Power all blocks surrounding block above torch - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YP); - } - } - - if (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) != 0x5) // Is torch standing on ground? If NOT (i.e. on wall), power block beneath - { - BLOCKTYPE Type = m_Chunk->GetBlock(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ); - - if (IsMechanism(Type)) // Still can't make a normal block powered though! - { - SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); - } - } - } - else - { - // Check if the block the torch is on is powered - int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ; - AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on - - cChunk * Neighbour = m_Chunk->GetRelNeighborChunk(X, Z); - if ((Neighbour == NULL) || !Neighbour->IsValid()) - { - return; - } - - // See if off state torch can be turned on again - if (AreCoordsDirectlyPowered(X, Y, Z, Neighbour)) - { - return; // Something matches, torch still powered - } - - // Block torch on not powered, can be turned on again! - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_ON, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); // Set self as powered -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - if (IsLeverOn(Meta)) - { - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - - eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); - - Dir = ReverseBlockFace(Dir); - - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - NIBBLETYPE MetaData = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) - { - if ((MetaData & 0x4) == 0) - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); - } - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); - } - } - else - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) - { - if ((MetaData & 0x4) != 0) - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & ~0x04); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); - } - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - if (IsButtonOn(Meta)) - { - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - - eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta); - Dir = ReverseBlockFace(Dir); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - static const struct // Define which directions the wire can receive power from - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, /* Wires on same level start */ - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, /* Wires on same level stop */ - { 1, 1, 0}, /* Wires one higher, surrounding self start */ - {-1, 1, 0}, - { 0, 1, 1}, - { 0, 1, -1}, /* Wires one higher, surrounding self stop */ - { 1, -1, 0}, /* Wires one lower, surrounding self start */ - {-1, -1, 0}, - { 0, -1, 1}, - { 0, -1, -1}, /* Wires one lower, surrounding self stop */ - } ; - - static const struct // Define which directions the wire will check for repeater prescence - { - int x, y, z; - } gSideCoords[] = - { - { 1, 0, 0 }, - {-1, 0, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 }, - { 0, 1, 0 }, - }; - - // Check to see if directly beside a power source - unsigned char MyPower; - if (!IsWirePowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower)) - { - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); - return; - } - - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - - if (MyPower < 1) - { - return; - } - - MyPower--; - - for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power - { - if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... - { - BLOCKTYPE Type = 0; - if (a_RelBlockY + 1 >= cChunkDef::Height) - { - continue; - } - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, Type)) - { - continue; - } - if (cBlockInfo::IsSolid(Type)) // If there is something solid above us (wire cut off)... - { - continue; // We don't receive power from that wire - } - } - else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us - { - BLOCKTYPE Type = 0; - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY, a_RelBlockZ + gCrossCoords[i].z, Type)) - { - continue; - } - if (cBlockInfo::IsSolid(Type)) - { - continue; - } - } - - BLOCKTYPE Type = 0; - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type)) - { - continue; - } - if (Type == E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - } - } - - for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them - { - BLOCKTYPE Type = 0; - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, Type)) - { - continue; - } - if (Type == E_BLOCK_REDSTONE_REPEATER_OFF) - { - SetBlockPowered(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - } - } - - // Wire still powered, power blocks beneath - SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, MyPower); - - switch (GetWireDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - case REDSTONE_NONE: - { - SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower); - break; - } - case REDSTONE_X_POS: - { - SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower); - break; - } - case REDSTONE_X_NEG: - { - SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower); - break; - } - case REDSTONE_Z_POS: - { - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower); - break; - } - case REDSTONE_Z_NEG: - { - SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower); - break; - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) -{ - /* Repeater Orientation Mini Guide: - =================================== - - | - | Z Axis - V - - X Axis ----> - - Repeater directions, values from a cWorld::GetBlockMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) lookup: - - East (Right) (X+): 0x1 - West (Left) (X-): 0x3 - North (Up) (Z-): 0x2 - South (Down) (Z+): 0x0 - // TODO: Add E_META_XXX enum entries for all meta values and update project with them - - Sun rises from East (X+) - - */ - - // Create a variable holding my meta to avoid multiple lookups. - NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON); - - if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise: - { - bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta); - if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked. - { - QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true); - } - else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked. - { - QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); - } - } -} - -void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() -{ - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();) - { - if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? - { - int RelBlockX = itr->a_RelBlockPos.x; - int RelBlockY = itr->a_RelBlockPos.y; - int RelBlockZ = itr->a_RelBlockPos.z; - BLOCKTYPE Block; - NIBBLETYPE Meta; - m_Chunk->GetBlockTypeMeta(RelBlockX, RelBlockY, RelBlockZ, Block, Meta); - if (itr->ShouldPowerOn) - { - if (Block != E_BLOCK_REDSTONE_REPEATER_ON) // For performance - { - m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); - } - - switch (Meta & 0x3) // We only want the direction (bottom) bits - { - case 0x0: - { - SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ); - SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM); - break; - } - case 0x1: - { - SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); - SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP); - break; - } - case 0x2: - { - SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ); - SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP); - break; - } - case 0x3: - { - SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); - SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM); - break; - } - } - } - else if (Block != E_BLOCK_REDSTONE_REPEATER_OFF) - { - m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta); - } - itr = m_RepeatersDelayList->erase(itr); - } - else - { - LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); - itr->a_ElapsedTicks++; - itr++; - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - if (IsPistonPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness) - { - cBlockPistonHandler::ExtendPiston(BlockX, a_RelBlockY, BlockZ, &m_World); - } - else - { - cBlockPistonHandler::RetractPiston(BlockX, a_RelBlockY, BlockZ, &m_World); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - class cSetPowerToDropSpenser : - public cRedstonePoweredCallback - { - bool m_IsPowered; - public: - cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - - virtual bool Item(cRedstonePoweredEntity * a_DropSpenser) override - { - a_DropSpenser->SetRedstonePower(m_IsPowered); - return false; - } - } DrSpSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); - - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); -} - - - - - -void cIncrementalRedstoneSimulator::HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) -{ - if (a_MyState == E_BLOCK_REDSTONE_LAMP_OFF) - { - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_ON, 0); - } - } - else - { - if (!AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_OFF, 0); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - m_Chunk->BroadcastSoundEffect("game.tnt.primed", (double)BlockX, (double)a_RelBlockY, (double)BlockZ, 0.5f, 0.6f); - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_AIR, 0); - m_World.SpawnPrimedTNT(BlockX + 0.5, a_RelBlockY + 0.5, BlockZ + 0.5); // 80 ticks to boom - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) - { - cChunkInterface ChunkInterface(m_World.GetChunkMap()); - if (!cBlockDoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ)) - { - cBlockDoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, true); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); - } - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); - } - } - else - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) - { - cChunkInterface ChunkInterface(m_World.GetChunkMap()); - if (cBlockDoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ)) - { - cBlockDoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, false); - m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); - } - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - class cSetPowerToCommandBlock : - public cCommandBlockCallback - { - bool m_IsPowered; - public: - cSetPowerToCommandBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - - virtual bool Item(cCommandBlockEntity * a_CommandBlock) override - { - a_CommandBlock->SetRedstonePower(m_IsPowered); - return false; - } - } CmdBlockSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); - - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithCommandBlockAt(BlockX, a_RelBlockY, BlockZ, CmdBlockSP); -} - - - - - -void cIncrementalRedstoneSimulator::HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType) -{ - switch (a_MyType) - { - case E_BLOCK_DETECTOR_RAIL: - { - if ((m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x08) == 0x08) - { - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType); - } - break; - } - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_POWERED_RAIL: - { - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0x08); - } - else - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x07); - } - break; - } - default: LOGD("Unhandled type of rail in %s", __FUNCTION__); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) - { - m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, true); - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); - } - } - else - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) - { - m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, false); - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - bool m_bAreCoordsPowered = AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - - if (m_bAreCoordsPowered) - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) - { - class cSetPowerToNoteBlock : - public cRedstonePoweredCallback - { - public: - cSetPowerToNoteBlock() {} - - virtual bool Item(cRedstonePoweredEntity * a_NoteBlock) override - { - a_NoteBlock->SetRedstonePower(true); - return false; - } - } NoteBlockSP; - - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); - } - } - else - { - if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) - { - SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX, BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); - - if (!m_World.IsChunkLighted(ChunkX, ChunkZ)) - { - m_World.QueueLightChunk(ChunkX, ChunkZ); - } - else - { - if (m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)) > 8) - { - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - } - else - { - WakeUp(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - switch (a_MyType) - { - case E_BLOCK_STONE_PRESSURE_PLATE: - { - // MCS feature - stone pressure plates can only be triggered by players :D - cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false); - - if (a_Player != NULL) - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); - } - else - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } - break; - } - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - { - class cPressurePlateCallback : - public cEntityCallback - { - public: - cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : - m_NumberOfEntities(0), - m_X(a_BlockX), - m_Y(a_BlockY), - m_Z(a_BlockZ) - { - } - - virtual bool Item(cEntity * a_Entity) override - { - Vector3f EntityPos = a_Entity->GetPosition(); - Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); - double Distance = (EntityPos - BlockPos).Length(); - - if (Distance <= 0.5) - { - m_NumberOfEntities++; - } - return false; - } - - bool GetPowerLevel(unsigned char & a_PowerLevel) const - { - a_PowerLevel = std::min(m_NumberOfEntities, MAX_POWER_LEVEL); - return (a_PowerLevel > 0); - } - - protected: - int m_NumberOfEntities; - - int m_X; - int m_Y; - int m_Z; - }; - - cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); - - unsigned char Power; - NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - if (PressurePlateCallback.GetPowerLevel(Power)) - { - if (Meta == E_META_PRESSURE_PLATE_RAISED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); - } - else - { - if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } - - break; - } - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - { - class cPressurePlateCallback : - public cEntityCallback - { - public: - cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : - m_NumberOfEntities(0), - m_X(a_BlockX), - m_Y(a_BlockY), - m_Z(a_BlockZ) - { - } - - virtual bool Item(cEntity * a_Entity) override - { - Vector3f EntityPos = a_Entity->GetPosition(); - Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); - double Distance = (EntityPos - BlockPos).Length(); - - if (Distance <= 0.5) - { - m_NumberOfEntities++; - } - return false; - } - - bool GetPowerLevel(unsigned char & a_PowerLevel) const - { - a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL); - return (a_PowerLevel > 0); - } - - protected: - int m_NumberOfEntities; - - int m_X; - int m_Y; - int m_Z; - }; - - cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); - - unsigned char Power; - NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - if (PressurePlateCallback.GetPowerLevel(Power)) - { - if (Meta == E_META_PRESSURE_PLATE_RAISED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); - } - else - { - if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } - - break; - } - case E_BLOCK_WOODEN_PRESSURE_PLATE: - { - class cPressurePlateCallback : - public cEntityCallback - { - public: - cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : - m_FoundEntity(false), - m_X(a_BlockX), - m_Y(a_BlockY), - m_Z(a_BlockZ) - { - } - - virtual bool Item(cEntity * a_Entity) override - { - Vector3f EntityPos = a_Entity->GetPosition(); - Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); - double Distance = (EntityPos - BlockPos).Length(); - - if (Distance <= 0.5) - { - m_FoundEntity = true; - return true; // Break out, we only need to know for plates that at least one entity is on top - } - return false; - } - - bool FoundEntity(void) const - { - return m_FoundEntity; - } - - protected: - bool m_FoundEntity; - - int m_X; - int m_Y; - int m_Z; - } ; - - cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); - - NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - if (PressurePlateCallback.FoundEntity()) - { - if (Meta == E_META_PRESSURE_PLATE_RAISED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); - } - else - { - if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) - { - m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); - } - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } - break; - } - default: - { - LOGD("Unimplemented pressure plate type %s in cRedstoneSimulator", ItemToFullString(a_MyType).c_str()); - break; - } - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; - int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; - int RelX = a_RelBlockX, RelZ = a_RelBlockZ; - bool FoundActivated = false; - eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); - - for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks - { - BLOCKTYPE Type; - NIBBLETYPE Meta; - - AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards); - m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta); - - if (Type == E_BLOCK_TRIPWIRE) - { - if (Meta == 0x1) - { - FoundActivated = true; - } - } - else if (Type == E_BLOCK_TRIPWIRE_HOOK) - { - if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards) - { - // Other hook facing in opposite direction - circuit completed! - break; - } - else - { - // Tripwire hook not connected at all, AND away all the power state bits - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - return; - } - } - else - { - // Tripwire hook not connected at all, AND away all the power state bits - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - return; - } - } - - if (FoundActivated) - { - // Connected and activated, set the 3rd and 4th highest bits - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC); - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - } - else - { - // Connected but not activated, AND away the highest bit - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4); - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - class cGetTrappedChestPlayers : - public cChestCallback - { - public: - cGetTrappedChestPlayers(void) : - m_NumberOfPlayers(0) - { - } - - virtual bool Item(cChestEntity * a_Chest) override - { - ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST); - m_NumberOfPlayers = a_Chest->GetNumberOfPlayers(); - return (m_NumberOfPlayers <= 0); - } - - unsigned char GetPowerLevel(void) const - { - return std::min(m_NumberOfPlayers, MAX_POWER_LEVEL); - } - - private: - int m_NumberOfPlayers; - - } GTCP; - - int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; - int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; - if (m_Chunk->DoWithChestAt(BlockX, a_RelBlockY, BlockZ, GTCP)) - { - SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, GTCP.GetPowerLevel()); - } - else - { - SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); - } -} - - - - - -void cIncrementalRedstoneSimulator::HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; - int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; - - class cTripwireCallback : - public cEntityCallback - { - public: - cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : - m_FoundEntity(false), - m_X(a_BlockX), - m_Y(a_BlockY), - m_Z(a_BlockZ) - { - } - - virtual bool Item(cEntity * a_Entity) override - { - cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1); - cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - - if (bbEntity.DoesIntersect(bbWire)) - { - m_FoundEntity = true; - return true; // One entity is sufficient to trigger the wire - } - return false; - } - - bool FoundEntity(void) const - { - return m_FoundEntity; - } - - protected: - bool m_FoundEntity; - - int m_X; - int m_Y; - int m_Z; - }; - - cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback); - - if (TripwireCallback.FoundEntity()) - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); - } - else - { - m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); - } -} - - - - - -bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, cChunk * a_Chunk) -{ - // Torches want to access neighbour's data when on a wall, hence the extra chunk parameter - - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - for (PoweredBlocksList::const_iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end(); ++itr) // Check powered list - { - if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - return true; - } - } - return false; -} - - - - - -bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list - { - if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - return true; - } - } - return false; -} - - - - - -bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) -{ - // Repeaters cannot be powered by any face except their back; verify that this is true for a source - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - - for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } - - switch (a_Meta & 0x3) - { - case 0x0: - { - // Flip the coords to check the back of the repeater - if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; } - break; - } - case 0x1: - { - if (itr->a_SourcePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; } - break; - } - case 0x2: - { - if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; } - break; - } - case 0x3: - { - if (itr->a_SourcePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; } - break; - } - } - } - - for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } - - switch (a_Meta & 0x3) - { - case 0x0: - { - if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; } - break; - } - case 0x1: - { - if (itr->a_MiddlePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; } - break; - } - case 0x2: - { - if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; } - break; - } - case 0x3: - { - if (itr->a_MiddlePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; } - break; - } - } - } - return false; // Couldn't find power source behind repeater -} - - - - - -bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) -{ - switch (a_Meta & 0x3) // We only want the 'direction' part of our metadata - { - // If the repeater is looking up or down (If parallel to the Z axis) - case 0x0: - case 0x2: - { - // Check if eastern(right) neighbor is a powered on repeater who is facing us - BLOCKTYPE Block = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater? - { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3; - if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked - } - - // Check if western(left) neighbor is a powered on repeater who is facing us - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) - { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3; - if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked - } - - break; - } - - // If the repeater is looking left or right (If parallel to the x axis) - case 0x1: - case 0x3: - { - // Check if southern(down) neighbor is a powered on repeater who is facing us - BLOCKTYPE Block = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) - { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3; - if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked - } - - // Check if northern(up) neighbor is a powered on repeater who is facing us - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) - { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3; - if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked - } - - break; - } - } - - return false; // None of the checks succeeded, I am not a locked repeater -} - - - - -bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) -{ - // Pistons cannot be powered through their front face; this function verifies that a source meets this requirement - - eBlockFace Face = cBlockPistonHandler::MetaDataToDirection(a_Meta); - int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; - int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; - - for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } - - AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face); - - if (!itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - return true; - } - - AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true); - } - - for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } - - AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face); - - if (!itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - return true; - } - - AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true); - } - return false; // Source was in front of the piston's front face -} - - - - -bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel) -{ - a_PowerLevel = 0; - int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; - int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; - - for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - continue; - } - a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); // Get the highest power level (a_PowerLevel is initialised already and there CAN be multiple levels for one block) - } - - for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list - { - if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) - { - continue; - } - - BLOCKTYPE Type = E_BLOCK_AIR; - int RelSourceX = itr->a_SourcePos.x - m_Chunk->GetPosX() * cChunkDef::Width; - int RelSourceZ = itr->a_SourcePos.z - m_Chunk->GetPosZ() * cChunkDef::Width; - if (!m_Chunk->UnboundedRelGetBlockType(RelSourceX, itr->a_SourcePos.y, RelSourceZ, Type) || (Type == E_BLOCK_REDSTONE_WIRE)) - { - continue; - } - a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); - } - - return (a_PowerLevel != 0); // Answer the inital question: is the wire powered? -} - - - - - -bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered) -{ - for (SimulatedPlayerToggleableList::const_iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr) - { - if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) - { - if (itr->WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current? - { - return false; // It was, coordinates are no longer simulated - } - else - { - return true; // It wasn't, don't resimulate block, and allow players to toggle - } - } - } - return false; // Block wasn't even in the list, not simulated -} - - - - - -void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel) -{ - BLOCKTYPE MiddleBlock = 0; - switch (a_Direction) - { - case BLOCK_FACE_XM: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX - 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - case BLOCK_FACE_XP: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX + 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - case BLOCK_FACE_YM: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - case BLOCK_FACE_YP: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - case BLOCK_FACE_ZM: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - case BLOCK_FACE_ZP: - { - if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, MiddleBlock)) - { - return; - } - - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); - - break; - } - default: - { - ASSERT(!"Unhandled face direction when attempting to set blocks as linked powered!"); // Zombies, that wasn't supposed to happen... - break; - } - } -} - - - - - -void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel) -{ - static const struct - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0 }, - { -1, 0, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 }, - { 0, 1, 0 }, - { 0, -1, 0 } - }; - - for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through struct to power all directions - { - SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_PowerLevel); - } -} - - - - - -void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX; - int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ; - - cChunk * Neighbour = m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelBlockX, a_RelBlockZ); // Adjust coordinates for the later call using these values - if ((Neighbour == NULL) || !Neighbour->IsValid()) - { - return; - } - - PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList(); // We need to insert the value into the chunk who owns the block position - for (PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) - { - if ( - itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && - itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) - ) - { - // Check for duplicates, update power level, don't add a new listing - itr->a_PowerLevel = a_PowerLevel; - return; - } - } - - // No need to get neighbouring chunk as we can guarantee that when something is powering us, the entry will be in our chunk - // TODO: on C++11 support, change this to a llama function pased to a std::remove_if - for (PoweredBlocksList::iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) - { - if ( - itr->a_BlockPos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) && - itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && - (m_Chunk->GetBlock(a_RelSourceX, a_RelSourceY, a_RelSourceZ) == E_BLOCK_REDSTONE_WIRE) - ) - { - BLOCKTYPE Block; - NIBBLETYPE Meta; - Neighbour->GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); - - if (Block == E_BLOCK_REDSTONE_WIRE) - { - if (Meta < a_PowerLevel) - { - m_PoweredBlocks->erase(itr); // Powering source with higher power level, allow it - break; - } - else - { - // Powered wires try to power their source - don't let them! - return; - } - } - } - } - - sPoweredBlocks RC; - RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ); - RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ); - RC.a_PowerLevel = a_PowerLevel; - Powered->push_back(RC); - Neighbour->SetIsRedstoneDirty(true); - m_Chunk->SetIsRedstoneDirty(true); -} - - - - - -void cIncrementalRedstoneSimulator::SetBlockLinkedPowered( - int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, - int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, - int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, - BLOCKTYPE a_MiddleBlock, unsigned char a_PowerLevel - ) -{ - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - int MiddleX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelMiddleX; - int MiddleZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelMiddleZ; - int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX; - int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ; - - if (!IsViableMiddleBlock(a_MiddleBlock)) - { - return; - } - - cChunk * Neighbour = m_Chunk->GetNeighborChunk(BlockX, BlockZ); - if ((Neighbour == NULL) || !Neighbour->IsValid()) - { - return; - } - - LinkedBlocksList * Linked = Neighbour->GetRedstoneSimulatorLinkedBlocksList(); - for (LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list - { - if ( - itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && - itr->a_MiddlePos.Equals(Vector3i(MiddleX, a_RelMiddleY, MiddleZ)) && - itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) - ) - { - // Check for duplicates, update power level, don't add a new listing - itr->a_PowerLevel = a_PowerLevel; - return; - } - } - - sLinkedPoweredBlocks RC; - RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ); - RC.a_MiddlePos = Vector3i(MiddleX, a_RelMiddleY, MiddleZ); - RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ); - RC.a_PowerLevel = a_PowerLevel; - Linked->push_back(RC); - Neighbour->SetIsRedstoneDirty(true); - m_Chunk->SetIsRedstoneDirty(true); -} - - - - - -void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered) -{ - for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr) - { - if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) - { - continue; - } - - if (itr->WasLastStatePowered != WasLastStatePowered) - { - // If power states different, update listing - itr->WasLastStatePowered = WasLastStatePowered; - return; - } - else - { - // If states the same, just ignore - return; - } - } - - // We have arrive here; no block must be in list - add one - sSimulatedPlayerToggleableList RC; - RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - RC.WasLastStatePowered = WasLastStatePowered; - m_SimulatedPlayerToggleableBlocks->push_back(RC); -} - - - - - -bool cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn) -{ - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr) - { - if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) - { - if (ShouldPowerOn == itr->ShouldPowerOn) // We are queued already for the same thing, don't replace entry - { - return false; - } - - // Already in here (normal to allow repeater to continue on powering and updating blocks in front) - just update info and quit - itr->a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2; // See below for description - itr->a_ElapsedTicks = 0; - itr->ShouldPowerOn = ShouldPowerOn; - return false; - } - } - - // Self not in list, add self to list - sRepeatersDelayList RC; - RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ); - - // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.) - // Multiply by 2 because in MCS, 1 redstone tick = 1 world tick, but in Vanilla, 1 redstone tick = 2 world ticks, and we need to maintain compatibility - RC.a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2; - - RC.a_ElapsedTicks = 0; - RC.ShouldPowerOn = ShouldPowerOn; - m_RepeatersDelayList->push_back(RC); - return true; -} - - - - - -void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_SourceX, int a_SourceY, int a_SourceZ, cChunk * a_Chunk, bool a_IsFirstCall) -{ - if (!a_IsFirstCall) // The neighbouring chunks passed when this parameter is false may be invalid - { - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - } - // TODO: on C++11 support, change both of these to llama functions pased to a std::remove_if - - for (PoweredBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end();) - { - if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) - { - itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->erase(itr); - a_Chunk->SetIsRedstoneDirty(true); - continue; - } - ++itr; - } - for (LinkedBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->end();) - { - if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) - { - itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->erase(itr); - a_Chunk->SetIsRedstoneDirty(true); - continue; - } - ++itr; - } - - if (a_IsFirstCall && AreCoordsOnChunkBoundary(a_SourceX, a_SourceY, a_SourceZ)) - { - // +- 2 to accomodate linked powered blocks - SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX - 2, a_SourceZ), false); - SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX + 2, a_SourceZ), false); - SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ - 2), false); - SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ + 2), false); - } -} - - - - - -cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - int Dir = REDSTONE_NONE; - - BLOCKTYPE NegX = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, NegX)) - { - if (IsPotentialSource(NegX)) - { - Dir |= (REDSTONE_X_POS); - } - } - - BLOCKTYPE PosX = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, PosX)) - { - if (IsPotentialSource(PosX)) - { - Dir |= (REDSTONE_X_NEG); - } - } - - BLOCKTYPE NegZ = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, NegZ)) - { - if (IsPotentialSource(NegZ)) - { - if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_POS; - } - } - - BLOCKTYPE PosZ = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, PosZ)) - { - if (IsPotentialSource(PosZ)) - { - if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_NEG; - } - } - return (eRedstoneDirection)Dir; -} - - - - - -bool cIncrementalRedstoneSimulator::IsLeverOn(NIBBLETYPE a_BlockMeta) -{ - // Extract the ON bit from metadata and return if true if it is set: - return ((a_BlockMeta & 0x8) == 0x8); -} - +#include "Globals.h" +#ifndef SELF_TEST +#include "IncrementalRedstoneSimulator.h" +#include "IncrementalRedstoneSimulator.inc" + +#include "Chunk.h" +#include "World.h" +#include "Blocks/GetHandlerCompileTimeTemplate.h" +#include "Blocks/BlockTorch.h" +#include "Blocks/BlockLever.h" +#include "Blocks/BlockButton.h" +#include "Blocks/BlockTripwireHook.h" +#include "Blocks/BlockDoor.h" +#include "Blocks/BlockPiston.h" +#include "BlockEntities/ChestEntity.h" + +#pragma clang diagnostic ignored "-Wweak-template-vtables" +template class cIncrementalRedstoneSimulator; +#endif diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 79740a8f6..bc2c4ffd0 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -6,23 +6,25 @@ /// Per-chunk data for the simulator, specified individual chunks to simulate typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData; +class cRedstonePoweredEntity; +typedef cItemCallback cRedstonePoweredCallback; - +template class GetHandlerCompileTime, class ChestType> class cIncrementalRedstoneSimulator : - public cRedstoneSimulator + public cRedstoneSimulator { - typedef cRedstoneSimulator super; + typedef cRedstoneSimulator super; public: - cIncrementalRedstoneSimulator(cWorld & a_World); + cIncrementalRedstoneSimulator(WorldType & a_World); ~cIncrementalRedstoneSimulator(); virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; + virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override; virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); } - virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; + virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override; enum eRedstoneDirection { @@ -82,9 +84,9 @@ private: SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks; RepeatersDelayList * m_RepeatersDelayList; - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); } - void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk, cChunk * a_OtherChunk = NULL); - cChunk * m_Chunk; + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); } + void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL); + ChunkType * m_Chunk; // We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly // In addition to being non-performant, it would stop the player from actually breaking said device @@ -159,12 +161,12 @@ private: /** Removes a block from the Powered and LinkedPowered lists Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests */ - void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, cChunk * a_Chunk, bool a_IsFirstCall = true); + void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, ChunkType * a_Chunk, bool a_IsFirstCall = true); /** Returns if a coordinate is powered or linked powered */ bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); } /** Returns if a coordinate is in the directly powered blocks list */ - bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, cChunk * a_Chunk); + bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk); /** Returns if a coordinate is in the indirectly powered blocks list */ bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */ @@ -312,5 +314,7 @@ private: }; - +#ifdef SELF_TEST +#include "IncrementalRedstoneSimulator.inc" +#endif diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc new file mode 100644 index 000000000..6d1f7b0ae --- /dev/null +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -0,0 +1,2208 @@ + +#include "IncrementalRedstoneSimulator.h" +#include "BoundingBox.h" +#include "BlockEntities/RedstonePoweredEntity.h" +#include "Blocks/ChunkInterface.h" + + + +template class GetHandlerCompileTime, class ChestType> +cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(WorldType & a_World) : + super(a_World), + m_RedstoneSimulatorChunkData(), + m_PoweredBlocks(), + m_LinkedPoweredBlocks(), + m_SimulatedPlayerToggleableBlocks(), + m_RepeatersDelayList(), + m_Chunk() +{ +} + + + + +template class GetHandlerCompileTime, class ChestType> +cIncrementalRedstoneSimulator::~cIncrementalRedstoneSimulator() +{ +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk) +{ + if ((a_Chunk == NULL) || !a_Chunk->IsValid()) + { + return; + } + else if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height)) + { + return; + } + + // We may be called with coordinates in a chunk that is not the first chunk parameter + // In that case, the actual chunk (which the coordinates are in), will be passed as the second parameter + // Use that Chunk pointer to get a relative position + + int RelX = 0; + int RelZ = 0; + BLOCKTYPE Block; + NIBBLETYPE Meta; + + if (a_OtherChunk != NULL) + { + RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width; + RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width; + a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); + + // If a_OtherChunk is passed (not NULL), it is the chunk that had a block change, and a_Chunk will be the neighbouring chunk of that block + // Because said neighbouring chunk does not know of this change but still needs to update its redstone, we set it to dirty + a_Chunk->SetIsRedstoneDirty(true); + } + else + { + RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; + RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; + a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); + } + + // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid + // Checking only when a block is changed, as opposed to every tick, also improves performance + + PoweredBlocksList * PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList(); + for (typename PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end();) + { + if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + ++itr; + continue; + } + + if (!IsPotentialSource(Block)) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = PoweredBlocks->erase(itr); + continue; + } + else if ( + // Changeable sources + ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || + ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || + ((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) || + (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || + ((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0)) + ) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = PoweredBlocks->erase(itr); + continue; + } + ++itr; + } + + LinkedBlocksList * LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); + // We loop through all values (insteading of breaking out at the first) to make sure everything is gone, as there can be multiple SourceBlock entries for one AddBlock coordinate + for (typename LinkedBlocksList::iterator itr = LinkedPoweredBlocks->begin(); itr != LinkedPoweredBlocks->end();) + { + if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + if (!IsPotentialSource(Block)) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = LinkedPoweredBlocks->erase(itr); + continue; + } + else if ( + // Things that can send power through a block but which depends on meta + ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || + ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || + (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) + ) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = LinkedPoweredBlocks->erase(itr); + continue; + } + } + else if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + if (!IsViableMiddleBlock(Block)) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = LinkedPoweredBlocks->erase(itr); + continue; + } + } + ++itr; + } + + SimulatedPlayerToggleableList * SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); + for (typename SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks->begin(); itr != SimulatedPlayerToggleableBlocks->end(); ++itr) + { + if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) + { + continue; + } + + if (!IsAllowedBlock(Block)) + { + LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z); + SimulatedPlayerToggleableBlocks->erase(itr); + break; + } + } + + RepeatersDelayList * RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); + for (typename RepeatersDelayList::iterator itr = RepeatersDelayList->begin(); itr != RepeatersDelayList->end(); ++itr) + { + if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) + { + continue; + } + + if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF)) + { + RepeatersDelayList->erase(itr); + break; + } + } + + if (a_OtherChunk != NULL) + { + // DO NOT touch our chunk's data structure if we are being called with coordinates from another chunk - this one caused me massive grief :P + return; + } + + cRedstoneSimulatorChunkData * RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData(); + for (cRedstoneSimulatorChunkData::iterator itr = RedstoneSimulatorChunkData->begin(); itr != RedstoneSimulatorChunkData->end(); ++itr) + { + if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block + { + if (!IsAllowedBlock(Block)) + { + itr->DataTwo = true; // The new blocktype is not redstone; it must be queued to be removed from this list + } + else + { + itr->DataTwo = false; + itr->Data = Block; // Update block information + } + return; + } + } + + if (!IsAllowedBlock(Block)) + { + return; + } + + for (cRedstoneSimulatorChunkData::iterator itr = a_Chunk->GetRedstoneSimulatorQueuedData()->begin(); itr != a_Chunk->GetRedstoneSimulatorQueuedData()->end(); ++itr) + { + if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) + { + // Can't have duplicates in here either, in case something adds the block again before the structure can written to the main chunk data + return; + } + } + a_Chunk->GetRedstoneSimulatorQueuedData()->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false)); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) +{ + m_RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData(); + if (m_RedstoneSimulatorChunkData->empty() && a_Chunk->GetRedstoneSimulatorQueuedData()->empty()) + { + return; + } + + m_RedstoneSimulatorChunkData->insert(m_RedstoneSimulatorChunkData->end(), a_Chunk->GetRedstoneSimulatorQueuedData()->begin(), a_Chunk->GetRedstoneSimulatorQueuedData()->end()); + a_Chunk->GetRedstoneSimulatorQueuedData()->clear(); + + m_PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList(); + m_RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); + m_SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); + m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); + m_Chunk = a_Chunk; + bool ShouldUpdateSimulateOnceBlocks = false; + + if (a_Chunk->IsRedstoneDirty()) + { + // Simulate the majority of devices only if something (blockwise or power-wise) has changed + // Make sure to allow the chunk to resimulate after the initial run if there was a power change (ShouldUpdateSimulateOnceBlocks helps to do this) + a_Chunk->SetIsRedstoneDirty(false); + ShouldUpdateSimulateOnceBlocks = true; + } + + HandleRedstoneRepeaterDelays(); + + for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();) + { + if (dataitr->DataTwo) + { + dataitr = m_RedstoneSimulatorChunkData->erase(dataitr); + continue; + } + + switch (dataitr->Data) + { + case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break; + + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + { + HandlePressurePlate(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + default: break; + } + + if (ShouldUpdateSimulateOnceBlocks) + { + switch (dataitr->Data) + { + case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRAPPED_CHEST: HandleTrappedChest(dataitr->x, dataitr->y, dataitr->z); break; + + case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_POWERED_RAIL: + { + HandleRail(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_IRON_DOOR: + { + HandleDoor(dataitr->x, dataitr->y, dataitr->z); + break; + } + case E_BLOCK_REDSTONE_LAMP_OFF: + case E_BLOCK_REDSTONE_LAMP_ON: + { + HandleRedstoneLamp(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + case E_BLOCK_DISPENSER: + case E_BLOCK_DROPPER: + { + HandleDropSpenser(dataitr->x, dataitr->y, dataitr->z); + break; + } + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + { + HandlePiston(dataitr->x, dataitr->y, dataitr->z); + break; + } + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + { + HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + { + HandleRedstoneTorch(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_WOODEN_BUTTON: + { + HandleRedstoneButton(dataitr->x, dataitr->y, dataitr->z); + break; + } + default: break; + } + } + ++dataitr; + } +} + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) +{ + if (AreCoordsOnChunkBoundary(a_BlockX, a_BlockY, a_BlockZ)) + { + // On a chunk boundary, alert all four sides (i.e. at least one neighbouring chunk) + AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); + + // Pass the original coordinates, because when adding things to our simulator lists, we get the chunk that they are in, and therefore any updates need to preseve their position + // RedstoneAddBlock to pass both the neighbouring chunk and the chunk which the coordinates are in and +- 2 in GetNeighbour() to accomodate for LinkedPowered blocks being 2 away from chunk boundaries + RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 2, a_BlockZ), a_Chunk); + RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 2, a_BlockZ), a_Chunk); + RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 2), a_Chunk); + RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 2), a_Chunk); + + return; + } + + // Not on boundary, just alert this chunk for speed + AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) +{ + static const struct // Define which directions the torch can power + { + int x, y, z; + } gCrossCoords[] = + { + { 1, 0, 0}, + {-1, 0, 0}, + { 0, 0, 1}, + { 0, 0, -1}, + { 0, 1, 0}, + } ; + + if (a_MyState == E_BLOCK_REDSTONE_TORCH_ON) + { + // Check if the block the torch is on is powered + int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ; + AddFaceDirection(X, Y, Z, GetHandlerCompileTime::type::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on + + ChunkType * Neighbour = m_Chunk->GetRelNeighborChunk(X, Z); + if ((Neighbour == NULL) || !Neighbour->IsValid()) + { + return; + } + + if (AreCoordsDirectlyPowered(X, Y, Z, Neighbour)) + { + // There was a match, torch goes off + m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + return; + } + + // Torch still on, make all 4(X, Z) + 1(Y) sides powered + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + { + BLOCKTYPE Type = 0; + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type)) + { + continue; + } + if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last) + { + if ( + IsMechanism(Type) && // Is it a mechanism? Not block/other torch etc. + (!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on + ) + { + SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + } + else + { + // Top side, power whatever is there, including blocks + SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ); + // Power all blocks surrounding block above torch + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YP); + } + } + + if (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) != 0x5) // Is torch standing on ground? If NOT (i.e. on wall), power block beneath + { + BLOCKTYPE Type = m_Chunk->GetBlock(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ); + + if (IsMechanism(Type)) // Still can't make a normal block powered though! + { + SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + } + } + else + { + // Check if the block the torch is on is powered + int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ; + AddFaceDirection(X, Y, Z, GetHandlerCompileTime::type::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on + + ChunkType * Neighbour = m_Chunk->GetRelNeighborChunk(X, Z); + if ((Neighbour == NULL) || !Neighbour->IsValid()) + { + return; + } + + // See if off state torch can be turned on again + if (AreCoordsDirectlyPowered(X, Y, Z, Neighbour)) + { + return; // Something matches, torch still powered + } + + // Block torch on not powered, can be turned on again! + m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_ON, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); // Set self as powered +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + if (IsLeverOn(Meta)) + { + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + + eBlockFace Dir = GetHandlerCompileTime::type::BlockMetaDataToBlockFace(Meta); + + Dir = ReverseBlockFace(Dir); + + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + NIBBLETYPE MetaData = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) + { + if ((MetaData & 0x4) == 0) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) + { + if ((MetaData & 0x4) != 0) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & ~0x04); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + if (IsButtonOn(Meta)) + { + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + + eBlockFace Dir = GetHandlerCompileTime::type::BlockMetaDataToBlockFace(Meta); + Dir = ReverseBlockFace(Dir); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + static const struct // Define which directions the wire can receive power from + { + int x, y, z; + } gCrossCoords[] = + { + { 1, 0, 0}, /* Wires on same level start */ + {-1, 0, 0}, + { 0, 0, 1}, + { 0, 0, -1}, /* Wires on same level stop */ + { 1, 1, 0}, /* Wires one higher, surrounding self start */ + {-1, 1, 0}, + { 0, 1, 1}, + { 0, 1, -1}, /* Wires one higher, surrounding self stop */ + { 1, -1, 0}, /* Wires one lower, surrounding self start */ + {-1, -1, 0}, + { 0, -1, 1}, + { 0, -1, -1}, /* Wires one lower, surrounding self stop */ + } ; + + static const struct // Define which directions the wire will check for repeater prescence + { + int x, y, z; + } gSideCoords[] = + { + { 1, 0, 0 }, + {-1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + { 0, 1, 0 }, + }; + + // Check to see if directly beside a power source + unsigned char MyPower; + if (!IsWirePowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower)) + { + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0); + this->m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + return; + } + + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + + if (MyPower < 1) + { + return; + } + + MyPower--; + + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power + { + if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... + { + BLOCKTYPE Type = 0; + if (a_RelBlockY + 1 >= cChunkDef::Height) + { + continue; + } + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, Type)) + { + continue; + } + if (cBlockInfo::IsSolid(Type)) // If there is something solid above us (wire cut off)... + { + continue; // We don't receive power from that wire + } + } + else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us + { + BLOCKTYPE Type = 0; + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY, a_RelBlockZ + gCrossCoords[i].z, Type)) + { + continue; + } + if (cBlockInfo::IsSolid(Type)) + { + continue; + } + } + + BLOCKTYPE Type = 0; + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type)) + { + continue; + } + if (Type == E_BLOCK_REDSTONE_WIRE) + { + SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + } + } + + for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them + { + BLOCKTYPE Type = 0; + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, Type)) + { + continue; + } + if (Type == E_BLOCK_REDSTONE_REPEATER_OFF) + { + SetBlockPowered(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + } + } + + // Wire still powered, power blocks beneath + SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, MyPower); + + switch (GetWireDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + case REDSTONE_NONE: + { + SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower); + break; + } + case REDSTONE_X_POS: + { + SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower); + break; + } + case REDSTONE_X_NEG: + { + SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower); + break; + } + case REDSTONE_Z_POS: + { + SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower); + break; + } + case REDSTONE_Z_NEG: + { + SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower); + break; + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) +{ + /* Repeater Orientation Mini Guide: + =================================== + + | + | Z Axis + V + + X Axis ----> + + Repeater directions, values from a WorldType::GetBlockMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) lookup: + + East (Right) (X+): 0x1 + West (Left) (X-): 0x3 + North (Up) (Z-): 0x2 + South (Down) (Z+): 0x0 + // TODO: Add E_META_XXX enum entries for all meta values and update project with them + + Sun rises from East (X+) + + */ + + // Create a variable holding my meta to avoid multiple lookups. + NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON); + + if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise: + { + bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta); + if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked. + { + QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true); + } + else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked. + { + QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); + } + } +} + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays() +{ + for (typename RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();) + { + if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? + { + int RelBlockX = itr->a_RelBlockPos.x; + int RelBlockY = itr->a_RelBlockPos.y; + int RelBlockZ = itr->a_RelBlockPos.z; + BLOCKTYPE Block; + NIBBLETYPE Meta; + m_Chunk->GetBlockTypeMeta(RelBlockX, RelBlockY, RelBlockZ, Block, Meta); + if (itr->ShouldPowerOn) + { + if (Block != E_BLOCK_REDSTONE_REPEATER_ON) // For performance + { + m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); + } + + switch (Meta & 0x3) // We only want the direction (bottom) bits + { + case 0x0: + { + SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM); + break; + } + case 0x1: + { + SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP); + break; + } + case 0x2: + { + SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP); + break; + } + case 0x3: + { + SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ); + SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM); + break; + } + } + } + else if (Block != E_BLOCK_REDSTONE_REPEATER_OFF) + { + m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta); + } + itr = m_RepeatersDelayList->erase(itr); + } + else + { + LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); + itr->a_ElapsedTicks++; + itr++; + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + if (IsPistonPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness) + { + GetHandlerCompileTime::type::ExtendPiston(BlockX, a_RelBlockY, BlockZ, &this->m_World); + } + else + { + GetHandlerCompileTime::type::RetractPiston(BlockX, a_RelBlockY, BlockZ, &this->m_World); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + class cSetPowerToDropSpenser : + public cRedstonePoweredCallback + { + bool m_IsPowered; + public: + cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + + virtual bool Item(cRedstonePoweredEntity * a_DropSpenser) override + { + a_DropSpenser->SetRedstonePower(m_IsPowered); + return false; + } + } DrSpSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, DrSpSP); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState) +{ + if (a_MyState == E_BLOCK_REDSTONE_LAMP_OFF) + { + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_ON, 0); + } + } + else + { + if (!AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_OFF, 0); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + m_Chunk->BroadcastSoundEffect("game.tnt.primed", (double)BlockX, (double)a_RelBlockY, (double)BlockZ, 0.5f, 0.6f); + m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_AIR, 0); + this->m_World.SpawnPrimedTNT(BlockX + 0.5, a_RelBlockY + 0.5, BlockZ + 0.5); // 80 ticks to boom + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + typedef typename GetHandlerCompileTime::type DoorHandler; + + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) + { + cChunkInterface ChunkInterface(this->m_World.GetChunkMap()); + if (!DoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ)) + { + DoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, true); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) + { + cChunkInterface ChunkInterface(this->m_World.GetChunkMap()); + if (DoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ)) + { + DoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, false); + m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); + } + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + class cSetPowerToCommandBlock : + public cRedstonePoweredCallback + { + bool m_IsPowered; + public: + cSetPowerToCommandBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + + virtual bool Item(cRedstonePoweredEntity * a_CommandBlock) override + { + a_CommandBlock->SetRedstonePower(m_IsPowered); + return false; + } + } CmdBlockSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, CmdBlockSP); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType) +{ + switch (a_MyType) + { + case E_BLOCK_DETECTOR_RAIL: + { + if ((m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x08) == 0x08) + { + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType); + } + break; + } + case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_POWERED_RAIL: + { + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0x08); + } + else + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x07); + } + break; + } + default: LOGD("Unhandled type of rail in %s", __FUNCTION__); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) + { + this->m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, true); + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) + { + this->m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, false); + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + bool m_bAreCoordsPowered = AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + + if (m_bAreCoordsPowered) + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) + { + class cSetPowerToNoteBlock : + public cRedstonePoweredCallback + { + public: + cSetPowerToNoteBlock() {} + + virtual bool Item(cRedstonePoweredEntity * a_NoteBlock) override + { + a_NoteBlock->SetRedstonePower(true); + return false; + } + } NoteBlockSP; + + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + m_Chunk->DoWithRedstonePoweredEntityAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP); + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) + { + SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX, BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); + + if (!this->m_World.IsChunkLighted(ChunkX, ChunkZ)) + { + this->m_World.QueueLightChunk(ChunkX, ChunkZ); + } + else + { + if (m_Chunk->GetTimeAlteredLight(this->m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)) > 8) + { + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + else + { + WakeUp(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + switch (a_MyType) + { + case E_BLOCK_STONE_PRESSURE_PLATE: + { + // MCS feature - stone pressure plates can only be triggered by players :D + cPlayer * a_Player = this->m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false); + + if (a_Player != NULL) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); + } + else + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } + break; + } + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: + { + class cPressurePlateCallback : + public cEntityCallback + { + public: + cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_NumberOfEntities(0), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + Vector3f EntityPos = a_Entity->GetPosition(); + Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); + double Distance = (EntityPos - BlockPos).Length(); + + if (Distance <= 0.5) + { + m_NumberOfEntities++; + } + return false; + } + + bool GetPowerLevel(unsigned char & a_PowerLevel) const + { + a_PowerLevel = std::min(m_NumberOfEntities, MAX_POWER_LEVEL); + return (a_PowerLevel > 0); + } + + protected: + int m_NumberOfEntities; + + int m_X; + int m_Y; + int m_Z; + }; + + cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); + this->m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); + + unsigned char Power; + NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + if (PressurePlateCallback.GetPowerLevel(Power)) + { + if (Meta == E_META_PRESSURE_PLATE_RAISED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); + } + else + { + if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } + + break; + } + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + { + class cPressurePlateCallback : + public cEntityCallback + { + public: + cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_NumberOfEntities(0), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + Vector3f EntityPos = a_Entity->GetPosition(); + Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); + double Distance = (EntityPos - BlockPos).Length(); + + if (Distance <= 0.5) + { + m_NumberOfEntities++; + } + return false; + } + + bool GetPowerLevel(unsigned char & a_PowerLevel) const + { + a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL); + return (a_PowerLevel > 0); + } + + protected: + int m_NumberOfEntities; + + int m_X; + int m_Y; + int m_Z; + }; + + cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); + this->m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); + + unsigned char Power; + NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + if (PressurePlateCallback.GetPowerLevel(Power)) + { + if (Meta == E_META_PRESSURE_PLATE_RAISED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); + } + else + { + if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } + + break; + } + case E_BLOCK_WOODEN_PRESSURE_PLATE: + { + class cPressurePlateCallback : + public cEntityCallback + { + public: + cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_FoundEntity(false), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + Vector3f EntityPos = a_Entity->GetPosition(); + Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); + double Distance = (EntityPos - BlockPos).Length(); + + if (Distance <= 0.5) + { + m_FoundEntity = true; + return true; // Break out, we only need to know for plates that at least one entity is on top + } + return false; + } + + bool FoundEntity(void) const + { + return m_FoundEntity; + } + + protected: + bool m_FoundEntity; + + int m_X; + int m_Y; + int m_Z; + } ; + + cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); + this->m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); + + NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + if (PressurePlateCallback.FoundEntity()) + { + if (Meta == E_META_PRESSURE_PLATE_RAISED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.5F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType); + } + else + { + if (Meta == E_META_PRESSURE_PLATE_DEPRESSED) + { + m_Chunk->BroadcastSoundEffect("random.click", (double)BlockX + 0.5, (double)a_RelBlockY + 0.1, (double)BlockZ + 0.5, 0.3F, 0.6F); + } + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } + break; + } + default: + { + LOGD("Unimplemented pressure plate type %s in cRedstoneSimulator", ItemToFullString(a_MyType).c_str()); + break; + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + int RelX = a_RelBlockX, RelZ = a_RelBlockZ; + bool FoundActivated = false; + eBlockFace FaceToGoTowards = GetHandlerCompileTime::type::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + + for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks + { + BLOCKTYPE Type; + NIBBLETYPE Meta; + + AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards); + m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta); + + if (Type == E_BLOCK_TRIPWIRE) + { + if (Meta == 0x1) + { + FoundActivated = true; + } + } + else if (Type == E_BLOCK_TRIPWIRE_HOOK) + { + if (ReverseBlockFace( GetHandlerCompileTime::type::MetadataToDirection(Meta)) == FaceToGoTowards) + { + // Other hook facing in opposite direction - circuit completed! + break; + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + return; + } + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + return; + } + } + + if (FoundActivated) + { + // Connected and activated, set the 3rd and 4th highest bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + else + { + // Connected but not activated, AND away the highest bit + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4); + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + class cGetTrappedChestPlayers : + public cChestCallback + { + public: + cGetTrappedChestPlayers(void) : + m_NumberOfPlayers(0) + { + } + + virtual bool Item(ChestType * a_Chest) override + { + ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST); + m_NumberOfPlayers = a_Chest->GetNumberOfPlayers(); + return (m_NumberOfPlayers <= 0); + } + + unsigned char GetPowerLevel(void) const + { + return std::min(m_NumberOfPlayers, MAX_POWER_LEVEL); + } + + private: + int m_NumberOfPlayers; + + } GTCP; + + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + if (m_Chunk->DoWithChestAt(BlockX, a_RelBlockY, BlockZ, GTCP)) + { + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, GTCP.GetPowerLevel()); + } + else + { + SetSourceUnpowered(BlockX, a_RelBlockY, BlockZ, m_Chunk); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + + class cTripwireCallback : + public cEntityCallback + { + public: + cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_FoundEntity(false), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1); + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + if (bbEntity.DoesIntersect(bbWire)) + { + m_FoundEntity = true; + return true; // One entity is sufficient to trigger the wire + } + return false; + } + + bool FoundEntity(void) const + { + return m_FoundEntity; + } + + protected: + bool m_FoundEntity; + + int m_X; + int m_Y; + int m_Z; + }; + + cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ); + this->m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback); + + if (TripwireCallback.FoundEntity()) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); + } + else + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk) +{ + // Torches want to access neighbour's data when on a wall, hence the extra chunk parameter + + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + for (typename PoweredBlocksList::const_iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end(); ++itr) // Check powered list + { + if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + return true; + } + } + return false; +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + for (typename LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list + { + if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + return true; + } + } + return false; +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) +{ + // Repeaters cannot be powered by any face except their back; verify that this is true for a source + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + + for (typename PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } + + switch (a_Meta & 0x3) + { + case 0x0: + { + // Flip the coords to check the back of the repeater + if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; } + break; + } + case 0x1: + { + if (itr->a_SourcePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; } + break; + } + case 0x2: + { + if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; } + break; + } + case 0x3: + { + if (itr->a_SourcePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; } + break; + } + } + } + + for (typename LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } + + switch (a_Meta & 0x3) + { + case 0x0: + { + if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; } + break; + } + case 0x1: + { + if (itr->a_MiddlePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; } + break; + } + case 0x2: + { + if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; } + break; + } + case 0x3: + { + if (itr->a_MiddlePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; } + break; + } + } + } + return false; // Couldn't find power source behind repeater +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) +{ + switch (a_Meta & 0x3) // We only want the 'direction' part of our metadata + { + // If the repeater is looking up or down (If parallel to the Z axis) + case 0x0: + case 0x2: + { + // Check if eastern(right) neighbor is a powered on repeater who is facing us + BLOCKTYPE Block = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater? + { + NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3; + if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked + } + + // Check if western(left) neighbor is a powered on repeater who is facing us + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + { + NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3; + if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked + } + + break; + } + + // If the repeater is looking left or right (If parallel to the x axis) + case 0x1: + case 0x3: + { + // Check if southern(down) neighbor is a powered on repeater who is facing us + BLOCKTYPE Block = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + { + NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3; + if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked + } + + // Check if northern(up) neighbor is a powered on repeater who is facing us + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + { + NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3; + if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked + } + + break; + } + } + + return false; // None of the checks succeeded, I am not a locked repeater +} + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta) +{ + // Pistons cannot be powered through their front face; this function verifies that a source meets this requirement + + eBlockFace Face = GetHandlerCompileTime::type::MetaDataToDirection(a_Meta); + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + + for (typename PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } + + AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face); + + if (!itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + return true; + } + + AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true); + } + + for (typename LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; } + + AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face); + + if (!itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + return true; + } + + AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true); + } + return false; // Source was in front of the piston's front face +} + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel) +{ + a_PowerLevel = 0; + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + + for (typename PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + continue; + } + a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); // Get the highest power level (a_PowerLevel is initialised already and there CAN be multiple levels for one block) + } + + for (typename LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list + { + if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) + { + continue; + } + + BLOCKTYPE Type = E_BLOCK_AIR; + int RelSourceX = itr->a_SourcePos.x - m_Chunk->GetPosX() * cChunkDef::Width; + int RelSourceZ = itr->a_SourcePos.z - m_Chunk->GetPosZ() * cChunkDef::Width; + if (!m_Chunk->UnboundedRelGetBlockType(RelSourceX, itr->a_SourcePos.y, RelSourceZ, Type) || (Type == E_BLOCK_REDSTONE_WIRE)) + { + continue; + } + a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); + } + + return (a_PowerLevel != 0); // Answer the inital question: is the wire powered? +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered) +{ + for (typename SimulatedPlayerToggleableList::const_iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr) + { + if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) + { + if (itr->WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current? + { + return false; // It was, coordinates are no longer simulated + } + else + { + return true; // It wasn't, don't resimulate block, and allow players to toggle + } + } + } + return false; // Block wasn't even in the list, not simulated +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel) +{ + BLOCKTYPE MiddleBlock = 0; + switch (a_Direction) + { + case BLOCK_FACE_XM: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX - 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + case BLOCK_FACE_XP: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX + 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + case BLOCK_FACE_YM: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + case BLOCK_FACE_YP: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + case BLOCK_FACE_ZM: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + case BLOCK_FACE_ZP: + { + if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, MiddleBlock)) + { + return; + } + + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel); + + break; + } + default: + { + ASSERT(!"Unhandled face direction when attempting to set blocks as linked powered!"); // Zombies, that wasn't supposed to happen... + break; + } + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel) +{ + static const struct + { + int x, y, z; + } gCrossCoords[] = + { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, + { 0, 1, 0 }, + { 0, -1, 0 } + }; + + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through struct to power all directions + { + SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_PowerLevel); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX; + int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ; + + ChunkType * Neighbour = m_Chunk->GetRelNeighborChunkAdjustCoords(a_RelBlockX, a_RelBlockZ); // Adjust coordinates for the later call using these values + if ((Neighbour == NULL) || !Neighbour->IsValid()) + { + return; + } + + PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList(); // We need to insert the value into the chunk who owns the block position + for (typename PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) + { + if ( + itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && + itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) + ) + { + // Check for duplicates, update power level, don't add a new listing + itr->a_PowerLevel = a_PowerLevel; + return; + } + } + + // No need to get neighbouring chunk as we can guarantee that when something is powering us, the entry will be in our chunk + // TODO: on C++11 support, change this to a llama function pased to a std::remove_if + for (typename PoweredBlocksList::iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) + { + if ( + itr->a_BlockPos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) && + itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && + (m_Chunk->GetBlock(a_RelSourceX, a_RelSourceY, a_RelSourceZ) == E_BLOCK_REDSTONE_WIRE) + ) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + Neighbour->GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); + + if (Block == E_BLOCK_REDSTONE_WIRE) + { + if (Meta < a_PowerLevel) + { + m_PoweredBlocks->erase(itr); // Powering source with higher power level, allow it + break; + } + else + { + // Powered wires try to power their source - don't let them! + return; + } + } + } + } + + sPoweredBlocks RC; + RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ); + RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ); + RC.a_PowerLevel = a_PowerLevel; + Powered->push_back(RC); + Neighbour->SetIsRedstoneDirty(true); + m_Chunk->SetIsRedstoneDirty(true); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetBlockLinkedPowered( + int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, + int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, + int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, + BLOCKTYPE a_MiddleBlock, unsigned char a_PowerLevel + ) +{ + int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; + int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + int MiddleX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelMiddleX; + int MiddleZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelMiddleZ; + int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX; + int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ; + + if (!IsViableMiddleBlock(a_MiddleBlock)) + { + return; + } + + ChunkType * Neighbour = m_Chunk->GetNeighborChunk(BlockX, BlockZ); + if ((Neighbour == NULL) || !Neighbour->IsValid()) + { + return; + } + + LinkedBlocksList * Linked = Neighbour->GetRedstoneSimulatorLinkedBlocksList(); + for (typename LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list + { + if ( + itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && + itr->a_MiddlePos.Equals(Vector3i(MiddleX, a_RelMiddleY, MiddleZ)) && + itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) + ) + { + // Check for duplicates, update power level, don't add a new listing + itr->a_PowerLevel = a_PowerLevel; + return; + } + } + + sLinkedPoweredBlocks RC; + RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ); + RC.a_MiddlePos = Vector3i(MiddleX, a_RelMiddleY, MiddleZ); + RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ); + RC.a_PowerLevel = a_PowerLevel; + Linked->push_back(RC); + Neighbour->SetIsRedstoneDirty(true); + m_Chunk->SetIsRedstoneDirty(true); +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered) +{ + for (typename SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr) + { + if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) + { + continue; + } + + if (itr->WasLastStatePowered != WasLastStatePowered) + { + // If power states different, update listing + itr->WasLastStatePowered = WasLastStatePowered; + return; + } + else + { + // If states the same, just ignore + return; + } + } + + // We have arrive here; no block must be in list - add one + sSimulatedPlayerToggleableList RC; + RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + RC.WasLastStatePowered = WasLastStatePowered; + m_SimulatedPlayerToggleableBlocks->push_back(RC); +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn) +{ + for (typename RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr) + { + if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) + { + if (ShouldPowerOn == itr->ShouldPowerOn) // We are queued already for the same thing, don't replace entry + { + return false; + } + + // Already in here (normal to allow repeater to continue on powering and updating blocks in front) - just update info and quit + itr->a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2; // See below for description + itr->a_ElapsedTicks = 0; + itr->ShouldPowerOn = ShouldPowerOn; + return false; + } + } + + // Self not in list, add self to list + sRepeatersDelayList RC; + RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + + // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.) + // Multiply by 2 because in MCS, 1 redstone tick = 1 world tick, but in Vanilla, 1 redstone tick = 2 world ticks, and we need to maintain compatibility + RC.a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2; + + RC.a_ElapsedTicks = 0; + RC.ShouldPowerOn = ShouldPowerOn; + m_RepeatersDelayList->push_back(RC); + return true; +} + + + + +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::SetSourceUnpowered(int a_SourceX, int a_SourceY, int a_SourceZ, ChunkType * a_Chunk, bool a_IsFirstCall) +{ + if (!a_IsFirstCall) // The neighbouring chunks passed when this parameter is false may be invalid + { + if ((a_Chunk == NULL) || !a_Chunk->IsValid()) + { + return; + } + } + // TODO: on C++11 support, change both of these to llama functions pased to a std::remove_if + + for (typename PoweredBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end();) + { + if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) + { + itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->erase(itr); + a_Chunk->SetIsRedstoneDirty(true); + continue; + } + ++itr; + } + for (typename LinkedBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->end();) + { + if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) + { + itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->erase(itr); + a_Chunk->SetIsRedstoneDirty(true); + continue; + } + ++itr; + } + + if (a_IsFirstCall && AreCoordsOnChunkBoundary(a_SourceX, a_SourceY, a_SourceZ)) + { + // +- 2 to accomodate linked powered blocks + SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX - 2, a_SourceZ), false); + SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX + 2, a_SourceZ), false); + SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ - 2), false); + SetSourceUnpowered(a_SourceX, a_SourceY, a_SourceZ, a_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ + 2), false); + } +} + + + + +template class GetHandlerCompileTime, class ChestType> +typename cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int Dir = REDSTONE_NONE; + + BLOCKTYPE NegX = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, NegX)) + { + if (IsPotentialSource(NegX)) + { + Dir |= (REDSTONE_X_POS); + } + } + + BLOCKTYPE PosX = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, PosX)) + { + if (IsPotentialSource(PosX)) + { + Dir |= (REDSTONE_X_NEG); + } + } + + BLOCKTYPE NegZ = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, NegZ)) + { + if (IsPotentialSource(NegZ)) + { + if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_POS; + } + } + + BLOCKTYPE PosZ = 0; + if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, PosZ)) + { + if (IsPotentialSource(PosZ)) + { + if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner + { + Dir ^= REDSTONE_X_POS; + Dir |= REDSTONE_X_NEG; + } + if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner + { + Dir ^= REDSTONE_X_NEG; + Dir |= REDSTONE_X_POS; + } + Dir |= REDSTONE_Z_NEG; + } + } + return (eRedstoneDirection)Dir; +} + + + + +template class GetHandlerCompileTime, class ChestType> +bool cIncrementalRedstoneSimulator::IsLeverOn(NIBBLETYPE a_BlockMeta) +{ + // Extract the ON bit from metadata and return if true if it is set: + return ((a_BlockMeta & 0x8) == 0x8); +} + + + + diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index f9ed47982..88e141e85 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -8,9 +8,9 @@ class cRedstoneNoopSimulator : - public cRedstoneSimulator + public cRedstoneSimulator { - typedef cRedstoneSimulator super; + typedef cRedstoneSimulator super; public: cRedstoneNoopSimulator(cWorld & a_World) : diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp deleted file mode 100644 index a83f21106..000000000 --- a/src/Simulator/RedstoneSimulator.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "Globals.h" - -#include "RedstoneSimulator.h" -#include "../World.h" - - - - - -cRedstoneSimulator::cRedstoneSimulator(cWorld & a_World) : - super(a_World) -{ -} - - - - - diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index b3e20c9a5..56843e37f 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -5,13 +5,16 @@ - +template class cRedstoneSimulator : - public cSimulator + public cSimulator { - typedef cSimulator super; + typedef cSimulator super; public: - cRedstoneSimulator(cWorld & a_World); + cRedstoneSimulator(WorldType & a_World) : + super(a_World) + { + } } ; diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h index 1262f2792..feb82b4d5 100644 --- a/src/Simulator/SandSimulator.h +++ b/src/Simulator/SandSimulator.h @@ -3,13 +3,15 @@ #include "Simulator.h" +/// Per-chunk data for the simulator, specified individual chunks to simulate; Data is not used +typedef cCoordWithIntList cSandSimulatorChunkData; - +#include "Chunk.h" /// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air. class cSandSimulator : - public cSimulator + public cSimulator { public: cSandSimulator(cWorld & a_World, cIniFile & a_IniFile); @@ -55,8 +57,7 @@ protected: -/// Per-chunk data for the simulator, specified individual chunks to simulate; Data is not used -typedef cCoordWithIntList cSandSimulatorChunkData; + diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index 0739f0187..7b944382b 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -1,50 +1,8 @@ -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Simulator.h" -#include "../World.h" -#include "../BlockID.h" -#include "../Defines.h" -#include "../Chunk.h" - - - - - -cSimulator::cSimulator(cWorld & a_World) - : m_World(a_World) -{ -} - - - - - -cSimulator::~cSimulator() -{ -} - - - - - -void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); - AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ)); - AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1)); - if (a_BlockY > 0) - { - AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk); - } - if (a_BlockY < cChunkDef::Height - 1) - { - AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk); - } -} - +#include "Globals.h" +#include "Simulator.inc" +#pragma clang diagnostic ignored "-Wweak-template-vtables" +template class cSimulator; diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index 4d9a18867..ff53b17e1 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -8,17 +8,12 @@ -class cWorld; -class cChunk; - - - - +template class cSimulator { public: - cSimulator(cWorld & a_World); + cSimulator(WorldType & a_World); virtual ~cSimulator(); /// Called in each tick, a_Dt is the time passed since the last tick, in msec @@ -26,7 +21,7 @@ public: /// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available virtual void SimulateChunk(float a_Dt, int a_ChunkX, - int a_ChunkZ, cChunk * a_Chunk) + int a_ChunkZ, ChunkType * a_Chunk) { UNUSED(a_Dt); UNUSED(a_ChunkX); @@ -35,7 +30,7 @@ public: } /// Called when a block changes - virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); + virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk); virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; @@ -43,9 +38,9 @@ protected: friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up /// Called to simulate a new block - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0; + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) = 0; - cWorld & m_World; + WorldType & m_World; } ; diff --git a/src/Simulator/Simulator.inc b/src/Simulator/Simulator.inc new file mode 100644 index 000000000..1599ea60f --- /dev/null +++ b/src/Simulator/Simulator.inc @@ -0,0 +1,49 @@ + + +#include "Simulator.h" +#include "../World.h" +#include "../BlockID.h" +#include "../Defines.h" +#include "../Chunk.h" + + + + +template +cSimulator::cSimulator(WorldType & a_World) + : m_World(a_World) +{ +} + + + + +template +cSimulator::~cSimulator() +{ +} + + + + +template +void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) +{ + AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); + AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ)); + AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ)); + AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1)); + AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1)); + if (a_BlockY > 0) + { + AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk); + } + if (a_BlockY < cChunkDef::Height - 1) + { + AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk); + } +} + + + + diff --git a/src/Simulator/SimulatorManager.cpp b/src/Simulator/SimulatorManager.cpp index 918bac7a1..dafdcd239 100644 --- a/src/Simulator/SimulatorManager.cpp +++ b/src/Simulator/SimulatorManager.cpp @@ -70,7 +70,7 @@ void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk -void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate) +void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate) { m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate)); } diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h index 31a709316..185141764 100644 --- a/src/Simulator/SimulatorManager.h +++ b/src/Simulator/SimulatorManager.h @@ -37,10 +37,10 @@ public: void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); - void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object! + void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object! protected: - typedef std::vector > cSimulators; + typedef std::vector *, int> > cSimulators; cWorld & m_World; cSimulators m_Simulators; diff --git a/src/World.cpp b/src/World.cpp index fdc0aebad..732c9f14c 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3258,7 +3258,7 @@ void cWorld::SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicke -cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile) +cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile) { AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "Incremental"); @@ -3268,11 +3268,11 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile) SimulatorName = "Incremental"; } - cRedstoneSimulator * res = NULL; + cRedstoneSimulator * res = NULL; if (NoCaseCompare(SimulatorName, "Incremental") == 0) { - res = new cIncrementalRedstoneSimulator(*this); + res = new cIncrementalRedstoneSimulator(*this); } else if (NoCaseCompare(SimulatorName, "noop") == 0) { diff --git a/src/World.h b/src/World.h index 274bd2dcf..e4fe2965f 100644 --- a/src/World.h +++ b/src/World.h @@ -33,6 +33,7 @@ class cFireSimulator; class cFluidSimulator; class cSandSimulator; +template class cRedstoneSimulator; class cItem; class cPlayer; @@ -502,7 +503,7 @@ public: inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; } - inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; } + inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; } /** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */ bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp @@ -910,7 +911,7 @@ private: cFluidSimulator * m_WaterSimulator; cFluidSimulator * m_LavaSimulator; cFireSimulator * m_FireSimulator; - cRedstoneSimulator * m_RedstoneSimulator; + cRedstoneSimulator * m_RedstoneSimulator; cCriticalSection m_CSPlayers; cPlayerList m_Players; @@ -1051,7 +1052,7 @@ private: cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock); /** Creates a new redstone simulator.*/ - cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile); + cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile); /** Adds the players queued in the m_PlayersToAdd queue into the m_Players list. Assumes it is called from the Tick thread. */ -- cgit v1.2.3 From b87585977fb60e3ffa44864dc8ba28a031e47e2f Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 11 Sep 2014 17:57:34 +0100 Subject: Don't include IncrementalRedsonteSimulator.inc when in SELF_TEST mode --- src/Simulator/IncrementalRedstoneSimulator.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index bc2c4ffd0..0120a3208 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -313,8 +313,3 @@ private: } }; - -#ifdef SELF_TEST -#include "IncrementalRedstoneSimulator.inc" -#endif - -- cgit v1.2.3 From c45bf7cf55cac42fd168df6d008cb814dd94eae1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 11 Sep 2014 20:06:28 +0200 Subject: 1.8: Fixed hangings. --- src/Entities/ItemFrame.cpp | 2 +- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol18x.cpp | 114 +++++++++++++++++++++++++++++++------------ src/Protocol/Protocol18x.h | 3 ++ 4 files changed, 89 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index 0bc10ec60..7f923ef61 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -26,7 +26,7 @@ void cItemFrame::OnRightClicked(cPlayer & a_Player) { // Item not empty, rotate, clipping values to zero to three inclusive m_Rotation++; - if (m_Rotation >= 4) + if (m_Rotation >= 8) { m_Rotation = 0; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index d83e86ece..2b0c8baf8 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2834,7 +2834,7 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) WriteByte(0xA2); WriteItem(Frame.GetItem()); WriteByte(0x3); - WriteByte(Frame.GetRotation()); + WriteByte(Frame.GetRotation() / 2); break; } default: break; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 2ea83351e..28fffd851 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -406,9 +406,7 @@ void cProtocol180::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet - Pkt.WriteInt(a_BlockX); - Pkt.WriteInt(a_BlockY); - Pkt.WriteInt(a_BlockZ); + Pkt.WritePosition(a_BlockX, a_BlockX, a_BlockZ); } @@ -702,12 +700,23 @@ void cProtocol180::SendLoginSuccess(void) void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) { ASSERT(m_State == 3); // In game mode? - - /*cPacketizer Pkt(*this, 0x10); // Spawn Painting packet + double PosX = a_Painting.GetPosX(); + double PosY = a_Painting.GetPosY(); + double PosZ = a_Painting.GetPosZ(); + + switch (a_Painting.GetDirection()) + { + case 0: PosZ += 1; break; + case 1: PosX -= 1; break; + case 2: PosZ -= 1; break; + case 3: PosX += 1; break; + } + + cPacketizer Pkt(*this, 0x10); // Spawn Painting packet Pkt.WriteVarInt(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName().c_str()); - Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ())); - Pkt.WriteChar(a_Painting.GetDirection());*/ + Pkt.WritePosition(PosX, PosY, PosZ); + Pkt.WriteChar(a_Painting.GetDirection()); } @@ -1194,7 +1203,7 @@ void cProtocol180::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) Pkt.WriteFPInt(a_FallingBlock.GetPosZ()); Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); - Pkt.WriteInt(((int)a_FallingBlock.GetBlockType()) | (((int)a_FallingBlock.GetBlockMeta()) << 16)); // Or 0x10 + Pkt.WriteInt(((int)a_FallingBlock.GetBlockType()) | (((int)a_FallingBlock.GetBlockMeta()) << 12)); Pkt.WriteShort((short)(a_FallingBlock.GetSpeedX() * 400)); Pkt.WriteShort((short)(a_FallingBlock.GetSpeedY() * 400)); Pkt.WriteShort((short)(a_FallingBlock.GetSpeedZ() * 400)); @@ -1231,15 +1240,22 @@ void cProtocol180::SendSpawnMob(const cMonster & a_Mob) void cProtocol180::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) { ASSERT(m_State == 3); // In game mode? - + double PosX = a_Entity.GetPosX(); + double PosZ = a_Entity.GetPosZ(); + double Yaw = a_Entity.GetYaw(); + if (a_ObjectType == 71) + { + FixItemFramePositions(a_ObjectData, PosX, PosZ, Yaw); + } + cPacketizer Pkt(*this, 0xe); // Spawn Object packet Pkt.WriteVarInt(a_Entity.GetUniqueID()); Pkt.WriteByte(a_ObjectType); - Pkt.WriteFPInt(a_Entity.GetPosX()); + Pkt.WriteFPInt(PosX); Pkt.WriteFPInt(a_Entity.GetPosY()); - Pkt.WriteFPInt(a_Entity.GetPosZ()); + Pkt.WriteFPInt(PosZ); Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteByteAngle(a_Entity.GetYaw()); + Pkt.WriteByteAngle(Yaw); Pkt.WriteInt(a_ObjectData); if (a_ObjectData != 0) { @@ -1416,14 +1432,11 @@ void cProtocol180::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, cons ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x33); - Pkt.WriteInt(a_BlockX); - Pkt.WriteShort((short)a_BlockY); - Pkt.WriteInt(a_BlockZ); - // Need to send only up to 15 chars, otherwise the client crashes (#598) - Pkt.WriteString(a_Line1.substr(0, 15)); - Pkt.WriteString(a_Line2.substr(0, 15)); - Pkt.WriteString(a_Line3.substr(0, 15)); - Pkt.WriteString(a_Line4.substr(0, 15)); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line1.c_str())); + Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line2.c_str())); + Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line3.c_str())); + Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line4.c_str())); } @@ -1637,6 +1650,41 @@ int cProtocol180::GetParticleID(const AString & a_ParticleName) +void cProtocol180::FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw) +{ + switch (a_ObjectData) + { + case 0: + { + a_PosZ += 1; + a_Yaw = 0; + break; + } + case 1: + { + a_PosX -= 1; + a_Yaw = 90; + break; + } + case 2: + { + a_PosZ -= 1; + a_Yaw = 180; + break; + } + case 3: + { + a_PosX += 1; + a_Yaw = 270; + break; + } + } +} + + + + + void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: @@ -2328,14 +2376,20 @@ void cProtocol180::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) { - HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); - HANDLE_READ(a_ByteBuffer, ReadBEShort, short, BlockY); - HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line1); - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line2); - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line3); - HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line4); - m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4); + int BlockX, BlockY, BlockZ; + if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ)) + { + return; + } + + AString Lines[4]; + for (int i = 0; i < 4; i++) + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line); + Lines[i] = Line.substr(1, Line.length() - 2); // Remove "" + } + + m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Lines[0], Lines[1], Lines[2], Lines[3]); } @@ -3062,9 +3116,9 @@ void cProtocol180::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) case cEntity::etItemFrame: { cItemFrame & Frame = (cItemFrame &)a_Entity; - WriteByte(0xA2); + WriteByte(0xA8); WriteItem(Frame.GetItem()); - WriteByte(0x3); + WriteByte(0x09); WriteByte(Frame.GetRotation()); break; } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 2b3063556..97ab3e93c 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -141,6 +141,9 @@ public: /** The 1.8 protocol use a particle id instead of a string. This function converts the name to the id. If the name is incorrect, it returns 0. */ static int GetParticleID(const AString & a_ParticleName); + /** Minecraft 1.8 use other locations to spawn the item frame. This function converts the 1.7 positions to 1.8 positions. */ + static void FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw); + protected: /** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */ -- cgit v1.2.3 From d815aeaefd965d58b2ed993021137de43a95958a Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 11 Sep 2014 22:21:53 +0200 Subject: 1.8: Fixed sign placing. --- src/Protocol/Protocol18x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 28fffd851..978ae7807 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -406,7 +406,7 @@ void cProtocol180::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet - Pkt.WritePosition(a_BlockX, a_BlockX, a_BlockZ); + Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); } -- cgit v1.2.3 From 6d5a5eb665d8f13dd3e4e7c279967556b0f9fa91 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 11 Sep 2014 22:27:35 +0200 Subject: Removed GetProtocolVersion() from the protocols. --- src/Protocol/Protocol.h | 8 ++------ src/Protocol/Protocol125.cpp | 3 +-- src/Protocol/Protocol132.cpp | 2 -- src/Protocol/Protocol14x.cpp | 3 --- src/Protocol/Protocol17x.cpp | 4 +--- src/Protocol/Protocol18x.cpp | 3 +-- src/Protocol/ProtocolRecognizer.cpp | 2 +- 7 files changed, 6 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 2b41b809c..8c9fadd1a 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -46,11 +46,11 @@ typedef unsigned char Byte; class cProtocol { public: - cProtocol(cClientHandle * a_Client, int a_ProtocolVersion) : - m_ProtocolVersion(a_ProtocolVersion), + cProtocol(cClientHandle * a_Client) : m_Client(a_Client) { } + virtual ~cProtocol() {} /// Called when client sends some data @@ -131,11 +131,7 @@ public: /// Returns the ServerID used for authentication through session.minecraft.net virtual AString GetAuthServerID(void) = 0; - /** Returns the protocol version of this protocol. */ - int GetProtocolVersion(void) const { return m_ProtocolVersion; } - protected: - int m_ProtocolVersion; cClientHandle * m_Client; cCriticalSection m_CSPacket; // Each SendXYZ() function must acquire this CS in order to send the whole packet at once diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 1d6049097..0c481024e 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -16,7 +16,6 @@ Documentation: #include "../ClientHandle.h" #include "../World.h" #include "ChunkDataSerializer.h" -#include "ProtocolRecognizer.h" #include "../Entities/Entity.h" #include "../Entities/ExpOrb.h" #include "../Mobs/Monster.h" @@ -133,7 +132,7 @@ typedef unsigned char Byte; cProtocol125::cProtocol125(cClientHandle * a_Client) : - super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_2_5), + super(a_Client), m_ReceivedData(32 KiB), m_LastSentDimension(dimNotSet) { diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 6fbc3a264..5fd2655b8 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -5,7 +5,6 @@ #include "Globals.h" #include "ChunkDataSerializer.h" -#include "ProtocolRecognizer.h" #include "Protocol132.h" #include "../Root.h" #include "../Server.h" @@ -79,7 +78,6 @@ cProtocol132::cProtocol132(cClientHandle * a_Client) : super(a_Client), m_IsEncrypted(false) { - m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_3_2; } diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp index 2d737acb4..d33314a2f 100644 --- a/src/Protocol/Protocol14x.cpp +++ b/src/Protocol/Protocol14x.cpp @@ -23,7 +23,6 @@ Implements the 1.4.x protocol classes representing these protocols: #include "../UI/Window.h" #include "../Entities/Pickup.h" #include "../Entities/FallingBlock.h" -#include "ProtocolRecognizer.h" #ifdef _MSC_VER #pragma warning(push) @@ -73,7 +72,6 @@ enum cProtocol142::cProtocol142(cClientHandle * a_Client) : super(a_Client) { - m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_4_2; } @@ -152,7 +150,6 @@ void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do cProtocol146::cProtocol146(cClientHandle * a_Client) : super(a_Client) { - m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_4_6; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 2b0c8baf8..b3c78a8ba 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -12,7 +12,6 @@ Implements the 1.7.x protocol classes: #include "Globals.h" #include "json/json.h" #include "Protocol17x.h" -#include "ProtocolRecognizer.h" #include "ChunkDataSerializer.h" #include "PolarSSL++/Sha1Checksum.h" @@ -93,7 +92,7 @@ extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; // cProtocol172: cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_7_2), + super(a_Client), m_ServerAddress(a_ServerAddress), m_ServerPort(a_ServerPort), m_State(a_State), @@ -3064,7 +3063,6 @@ void cProtocol172::cPacketizer::WriteEntityProperties(const cEntity & a_Entity) cProtocol176::cProtocol176(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { - m_ProtocolVersion = cProtocolRecognizer::PROTO_VERSION_1_7_6; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 978ae7807..142cae6a5 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -11,7 +11,6 @@ Implements the 1.8.x protocol classes: #include "Globals.h" #include "json/json.h" #include "Protocol18x.h" -#include "ProtocolRecognizer.h" #include "ChunkDataSerializer.h" #include "PolarSSL++/Sha1Checksum.h" @@ -92,7 +91,7 @@ extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; // cProtocol180: cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client, cProtocolRecognizer::PROTO_VERSION_1_8_0), + super(a_Client), m_ServerAddress(a_ServerAddress), m_ServerPort(a_ServerPort), m_State(a_State), diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index cf63583db..28b2b9c4b 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -26,7 +26,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : - super(a_Client, 0), + super(a_Client), m_Protocol(NULL), m_Buffer(512) { -- cgit v1.2.3 From c7044fa1dd77a04c57780443a5dc88165c2d2ca1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 11 Sep 2014 23:17:27 +0200 Subject: 1.8: Fixed inventory open packet. --- src/Protocol/Protocol18x.cpp | 5 ++--- src/UI/Window.cpp | 28 ++++++++++++++++++++++++++++ src/UI/Window.h | 3 ++- 3 files changed, 32 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 142cae6a5..04af848dc 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1515,10 +1515,9 @@ void cProtocol180::SendWindowOpen(const cWindow & a_Window) cPacketizer Pkt(*this, 0x2d); Pkt.WriteChar(a_Window.GetWindowID()); - Pkt.WriteChar(a_Window.GetWindowType()); - Pkt.WriteString(a_Window.GetWindowTitle()); + Pkt.WriteString(a_Window.GetWindowTypeName()); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_Window.GetWindowTitle().c_str())); Pkt.WriteChar(a_Window.GetNumNonInventorySlots()); - Pkt.WriteBool(true); if (a_Window.GetWindowType() == cWindow::wtAnimalChest) { Pkt.WriteInt(0); // TODO: The animal's EntityID diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 66900269f..1b7b07f77 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -57,6 +57,34 @@ cWindow::~cWindow() +const AString cWindow::GetWindowTypeName(void) const +{ + switch (m_WindowType) + { + case wtChest: return "minecraft:chest"; + case wtWorkbench: return "minecraft:crafting_table"; + case wtFurnace: return "minecraft:furnace"; + case wtDropSpenser: return "minecraft:dispenser"; + case wtEnchantment: return "minecraft:enchanting_table"; + case wtBrewery: return "minecraft:brewing_stand"; + case wtNPCTrade: return "minecraft:villager"; + case wtBeacon: return "minecraft:beacon"; + case wtAnvil: return "minecraft:anvil"; + case wtHopper: return "minecraft:hopper"; + case wtDropper: return "minecraft:dropper"; + case wtAnimalChest: return "EntityHorse"; + default: + { + ASSERT(!"Unknown inventory type!"); + return ""; + } + } +} + + + + + int cWindow::GetNumSlots(void) const { int res = 0; diff --git a/src/UI/Window.h b/src/UI/Window.h index 3d860407f..bc5becf11 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -63,7 +63,7 @@ public: wtBeacon = 7, wtAnvil = 8, wtHopper = 9, - // Unknown: 10 + wtDropper = 10, wtAnimalChest = 11, }; @@ -76,6 +76,7 @@ public: char GetWindowID(void) const { return m_WindowID; } // tolua_export int GetWindowType(void) const { return m_WindowType; } // tolua_export + const AString GetWindowTypeName(void) const; // tolua_export cWindowOwner * GetOwner(void) { return m_Owner; } void SetOwner( cWindowOwner * a_Owner) { m_Owner = a_Owner; } -- cgit v1.2.3 From a02d96d1f574ed08a50129413fca71154354b300 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 00:36:46 +0200 Subject: 1.8: Fixed enderman spawning. --- src/Protocol/Protocol18x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 04af848dc..abc9f7e60 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -3223,7 +3223,7 @@ void cProtocol180::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) case cMonster::mtEnderman: { - WriteByte(0x10); + WriteByte(0x30); WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); WriteByte(0x11); WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); -- cgit v1.2.3 From e10237fb4dc7e9c9c3d0a67cfd2672fbb1d9083d Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 00:41:07 +0200 Subject: 1.8: Enderman, byte -> short --- src/Protocol/Protocol18x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index abc9f7e60..154da212c 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -3224,7 +3224,7 @@ void cProtocol180::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) case cMonster::mtEnderman: { WriteByte(0x30); - WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); + WriteShort((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); WriteByte(0x11); WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); WriteByte(0x12); -- cgit v1.2.3 From 85ec697d32c3e5a4b2e711c25c6f836a0a948419 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 01:15:21 +0200 Subject: 1.8: Fixed workbench, enchanting and anvil window. --- src/Protocol/Protocol18x.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 154da212c..ba39bb3e6 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1506,18 +1506,34 @@ void cProtocol180::SendWindowClose(const cWindow & a_Window) void cProtocol180::SendWindowOpen(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + if (a_Window.GetWindowType() < 0) { // Do not send this packet for player inventory windows return; } - + cPacketizer Pkt(*this, 0x2d); Pkt.WriteChar(a_Window.GetWindowID()); Pkt.WriteString(a_Window.GetWindowTypeName()); Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_Window.GetWindowTitle().c_str())); - Pkt.WriteChar(a_Window.GetNumNonInventorySlots()); + + switch (a_Window.GetWindowType()) + { + case cWindow::wtWorkbench: + case cWindow::wtEnchantment: + case cWindow::wtAnvil: + { + Pkt.WriteChar(0); + break; + } + default: + { + Pkt.WriteChar(a_Window.GetNumNonInventorySlots()); + break; + } + } + if (a_Window.GetWindowType() == cWindow::wtAnimalChest) { Pkt.WriteInt(0); // TODO: The animal's EntityID -- cgit v1.2.3 From 4e2d75bde56a8c0913006b5978ff418ea042ef0b Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 01:37:19 +0200 Subject: 1.8: Fixed eating. --- src/ClientHandle.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3b32b06b9..2bffc3cb1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1207,6 +1207,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if ( (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block + IsValidBlock(a_HeldItem.m_ItemType) && ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() >= 5) ) { -- cgit v1.2.3 From 8151c79a875a327e364def4960527514ee584136 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 01:44:20 +0200 Subject: 1.8: Fixed block entities. --- src/Protocol/Protocol18x.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index ba39bb3e6..4d74995db 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1403,9 +1403,7 @@ void cProtocol180::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x35); // Update tile entity packet - Pkt.WriteInt(a_BlockEntity.GetPosX()); - Pkt.WriteShort(a_BlockEntity.GetPosY()); - Pkt.WriteInt(a_BlockEntity.GetPosZ()); + Pkt.WritePosition(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); Byte Action = 0; switch (a_BlockEntity.GetBlockType()) @@ -2995,11 +2993,7 @@ void cProtocol180::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt } Writer.Finish(); - - AString Compressed; - CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); - WriteShort((short)Compressed.size()); - WriteBuf(Compressed.data(), Compressed.size()); + WriteBuf(Writer.GetResult().data(), Writer.GetResult().size()); } -- cgit v1.2.3 From eb19eff5ac46515360b3af0647135c5460342ed7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 02:00:28 +0200 Subject: 1.8: Added difficulty sending --- src/Protocol/Protocol18x.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 4d74995db..59852227c 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -665,6 +665,12 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) cPacketizer Pkt(*this, 0x05); // Spawn Position packet Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); } + + // Send the server difficulty: + { + cPacketizer Pkt(*this, 0x41); + Pkt.WriteChar(1); + } // Send player abilities: SendPlayerAbilities(); -- cgit v1.2.3 From 34bcd3dd589cca6d525633ad4445ec7700578995 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 02:42:04 +0200 Subject: 1.8: Fixed ReadItem() --- src/ByteBuffer.cpp | 2 +- src/Protocol/Protocol18x.cpp | 58 +++++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 94684afb8..851c63858 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -267,7 +267,7 @@ size_t cByteBuffer::GetReadableSpace(void) const } // Single readable space partition: ASSERT(m_WritePos >= m_ReadPos); - return m_WritePos - m_ReadPos ; + return m_WritePos - m_ReadPos; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 59852227c..9553dec1a 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1822,7 +1822,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error - LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", + LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen ); @@ -2594,8 +2594,11 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) // Read the metadata AString Metadata; - a_ByteBuffer.ReadAll(Metadata); - + if (a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - 1)) + { + return false; + } + ParseItemMetadata(a_Item, Metadata); return true; } @@ -2781,37 +2784,54 @@ void cProtocol180::AddChatPartStyle(Json::Value & a_Value, const AString & a_Par cProtocol180::cPacketizer::~cPacketizer() { - AString DataToSend; - - // Send the packet length UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace(); + AString PacketData, CompressedPacket; + m_Out.ReadAll(PacketData); + m_Out.CommitRead(); - if (m_Protocol.m_State == 3) + if ((m_Protocol.m_State == 3) && (PacketLen >= 256)) + { + if (!cProtocol180::CompressPacket(PacketData, CompressedPacket)) + { + return; + } + } + else if (m_Protocol.m_State == 3) { m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen + 1); m_Protocol.m_OutPacketLenBuffer.WriteVarInt(0); + + AString LengthData; + m_Protocol.m_OutPacketLenBuffer.ReadAll(LengthData); + m_Protocol.SendData(LengthData.data(), LengthData.size()); } else { m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen); + + AString LengthData; + m_Protocol.m_OutPacketLenBuffer.ReadAll(LengthData); + m_Protocol.SendData(LengthData.data(), LengthData.size()); } - m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend); - m_Protocol.SendData(DataToSend.data(), DataToSend.size()); - m_Protocol.m_OutPacketLenBuffer.CommitRead(); - - // Send the packet data: - m_Out.ReadAll(DataToSend); - m_Protocol.SendData(DataToSend.data(), DataToSend.size()); - m_Out.CommitRead(); - + + if (CompressedPacket.empty()) + { + m_Protocol.m_OutPacketLenBuffer.CommitRead(); + m_Protocol.SendData(PacketData.data(), PacketData.size()); + } + else + { + m_Protocol.SendData(CompressedPacket.data(), CompressedPacket.size()); + } + // Log the comm into logfile: if (g_ShouldLogCommOut) { AString Hex; - ASSERT(DataToSend.size() > 0); - CreateHexDump(Hex, DataToSend.data() + 1, DataToSend.size() - 1, 16); + ASSERT(PacketData.size() > 0); + CreateHexDump(Hex, PacketData.data() + 1, PacketData.size() - 1, 16); m_Protocol.m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload:\n%s\n", - DataToSend[0], DataToSend[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str() + PacketData[0], PacketData[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str() ); } } -- cgit v1.2.3 From 0d34fc9f31f6b4eabcc52236b7c2c0f6b9139041 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 13:01:23 +0200 Subject: Fixed wrong buffer length in the 1.8 protocol. --- src/Protocol/Protocol18x.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 9553dec1a..735700dda 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1753,7 +1753,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) m_ReceivedData.ResetRead(); break; } - cByteBuffer bb(PacketLen + 1); + cByteBuffer bb(PacketLen); VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); m_ReceivedData.CommitRead(); @@ -1819,7 +1819,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) return; } - if (bb.GetReadableSpace() != 1) + if (bb.GetReadableSpace() != 0) { // Read more or less than packet length, report as error LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", @@ -2334,10 +2334,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) - { - return; - } + a_ByteBuffer.ReadAll(Data); m_Client->HandlePluginMessage(Channel, Data); } @@ -2594,10 +2591,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) // Read the metadata AString Metadata; - if (a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - 1)) - { - return false; - } + a_ByteBuffer.ReadAll(Metadata); ParseItemMetadata(a_Item, Metadata); return true; -- cgit v1.2.3 From f2c5d8a7615ca46f1894ae5ad651a92cee421a18 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 13:19:33 +0200 Subject: Fixed many right click issues. --- src/ClientHandle.cpp | 14 ++++++++++---- src/Items/ItemHoe.h | 10 +++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 2bffc3cb1..642a5246a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1204,15 +1204,16 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); cWorld * World = m_Player->GetWorld(); + bool AreRealCoords = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5; if ( (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block IsValidBlock(a_HeldItem.m_ItemType) && - ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() >= 5) + !AreRealCoords ) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if ((a_BlockX >= 0) && (a_BlockY >= 0) && (a_BlockZ >= 0)) + if ((a_BlockX != -1) && (a_BlockY >= 0) && (a_BlockZ != -1)) { World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); if (a_BlockY < cChunkDef::Height - 1) @@ -1228,11 +1229,16 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e return; } + if (!AreRealCoords) + { + a_BlockFace = BLOCK_FACE_NONE; + } + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { // A plugin doesn't agree with the action, replace the block on the client and quit: - if ((a_BlockX >= 0) && (a_BlockY >= 0) && (a_BlockZ >= 0)) + if (AreRealCoords) { cChunkInterface ChunkInterface(World->GetChunkMap()); BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); @@ -1278,7 +1284,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e return; } - if ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5) + if (AreRealCoords) { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index 8d0b71478..987357739 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -18,11 +18,15 @@ public: { } - virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override + virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { - BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (a_Dir == BLOCK_FACE_NONE) + { + return false; + } - if ((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) + BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (IsBlockTypeOfDirt(Block)) { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); a_Player->UseEquippedItem(); -- cgit v1.2.3 From 1849e620fcd564c02af059e3863a2fa7d185d2f9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 13:49:08 +0200 Subject: Added flint drop and fence gate meta reset. --- src/Blocks/BlockFenceGate.h | 6 ++++++ src/Blocks/BlockGravel.h | 11 +++++++++++ 2 files changed, 17 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index ae99a4f94..3041dd46c 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -17,6 +17,12 @@ public: } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.Add(E_BLOCK_FENCE_GATE, 1, 0); // Reset meta to zero + } + + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockGravel.h b/src/Blocks/BlockGravel.h index 717bd5f5f..3a9fbd170 100644 --- a/src/Blocks/BlockGravel.h +++ b/src/Blocks/BlockGravel.h @@ -15,6 +15,17 @@ public: : cBlockHandler(a_BlockType) { } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.Add(E_BLOCK_GRAVEL, 1, 0); + + cFastRandom Random; + if (Random.NextInt(30) == 0) + { + a_Pickups.Add(E_ITEM_FLINT, 1, 0); + } + } } ; -- cgit v1.2.3 From abcae75992ef283c05465c68a9d71b413bc7cb35 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 14:08:56 +0200 Subject: Fixed iron ore drop. --- src/Blocks/BlockOre.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockOre.h b/src/Blocks/BlockOre.h index 0067d475f..f6ea3aa3c 100644 --- a/src/Blocks/BlockOre.h +++ b/src/Blocks/BlockOre.h @@ -51,7 +51,8 @@ public: } default: { - ASSERT(!"Unhandled ore!"); + a_Pickups.push_back(cItem(m_BlockType)); + break; } } } -- cgit v1.2.3 From a1716bb4156c4a85244bcd64b63ebee229fabb54 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 15:57:37 +0200 Subject: Players in survival mode are not allowed to break a bedrock. --- src/ClientHandle.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index a6d7c3066..e2759dc6c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1134,6 +1134,12 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo FinishDigAnimation(); + if (!m_Player->IsGameModeCreative() && (a_OldBlock == E_BLOCK_BEDROCK)) + { + Kick("You can't break a bedrock!"); + return; + } + cWorld * World = m_Player->GetWorld(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); -- cgit v1.2.3 From 3f000deb3b354722d4c8a596cfeecb6ab865c1bb Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 15:59:46 +0200 Subject: Disabled mobspawner itemdrop. --- src/Items/ItemHandler.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 67c945ce4..6ffcc718d 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -582,6 +582,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_SNOW: case E_BLOCK_VINES: case E_BLOCK_PACKED_ICE: + case E_BLOCK_MOB_SPAWNER: { return false; } -- cgit v1.2.3 From d07ef85ee310486c07ce9905ef66c1cb31549617 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 16:41:23 +0200 Subject: Spawn exp if you break a mob spawner. --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockMobSpawner.h | 40 ++++++++++++++++++++++++++++++++++++++++ src/Blocks/WorldInterface.h | 3 +++ src/Items/ItemPickaxe.h | 1 + src/Protocol/Protocol17x.cpp | 6 +++--- src/World.h | 2 +- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/Blocks/BlockMobSpawner.h (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 34925a252..8a8bdd3c8 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -47,6 +47,7 @@ #include "BlockLilypad.h" #include "BlockLever.h" #include "BlockMelon.h" +#include "BlockMobSpawner.h" #include "BlockMushroom.h" #include "BlockMycelium.h" #include "BlockNetherWart.h" @@ -244,6 +245,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType); + case E_BLOCK_MOB_SPAWNER: return new cBlockMobSpawnerHandler (a_BlockType); case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType); case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); diff --git a/src/Blocks/BlockMobSpawner.h b/src/Blocks/BlockMobSpawner.h new file mode 100644 index 000000000..a51fbaafc --- /dev/null +++ b/src/Blocks/BlockMobSpawner.h @@ -0,0 +1,40 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Items/ItemHandler.h" + + + + + +class cBlockMobSpawnerHandler : + public cBlockHandler +{ +public: + cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // No pickups + } + + + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + cItemHandler * Handler = a_Player->GetEquippedItem().GetHandler(); + if (a_Player->IsGameModeCreative() || !Handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER)) + { + return; + } + + cFastRandom Random; + int Reward = 15 + Random.NextInt(15) + Random.NextInt(15); + a_WorldInterface.SpawnExperienceOrb((double)a_BlockX, (double)a_BlockY + 1, (double)a_BlockZ, Reward); + } +} ; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index b43d011d8..889ef1d87 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -35,6 +35,9 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; + /** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */ + virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0; + /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0; diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index 17fd96822..e0cf5d711 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -81,6 +81,7 @@ public: case E_BLOCK_STONE_BRICK_STAIRS: case E_BLOCK_NETHER_BRICK_STAIRS: case E_BLOCK_CAULDRON: + case E_BLOCK_MOB_SPAWNER: { return PickaxeLevel() >= 1; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f24ef320d..f07f6a928 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1033,9 +1033,9 @@ void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb) cPacketizer Pkt(*this, 0x11); Pkt.WriteVarInt(a_ExpOrb.GetUniqueID()); - Pkt.WriteInt((int) a_ExpOrb.GetPosX()); - Pkt.WriteInt((int) a_ExpOrb.GetPosY()); - Pkt.WriteInt((int) a_ExpOrb.GetPosZ()); + Pkt.WriteFPInt(a_ExpOrb.GetPosX()); + Pkt.WriteFPInt(a_ExpOrb.GetPosY()); + Pkt.WriteFPInt(a_ExpOrb.GetPosZ()); Pkt.WriteShort(a_ExpOrb.GetReward()); } diff --git a/src/World.h b/src/World.h index 274bd2dcf..0c57e6611 100644 --- a/src/World.h +++ b/src/World.h @@ -469,7 +469,7 @@ public: int SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content = cItem(), int a_BlockHeight = 1); /** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */ - int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); + virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) override; /** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */ void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1); -- cgit v1.2.3 From 7f42ba9fc117674635a840b860f0d3a6de818b99 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Fri, 12 Sep 2014 16:48:37 +0200 Subject: Fixed 1.8 Item stacking and block harvesting --- src/BlockID.h | 2 +- src/Items/ItemHandler.cpp | 68 ++++++++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 5f2ff15cc..45e71d85d 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -385,7 +385,7 @@ enum ENUM_ITEM_ID E_ITEM_RAW_RABBIT = 411, E_ITEM_COOKED_RABBIT = 412, E_ITEM_RABBIT_STEW = 413, - E_ITEM_RABBITS_FOOD = 414, + E_ITEM_RABBITS_FOOT = 414, E_ITEM_RABBIT_HIDE = 415, E_ITEM_ARMOR_STAND = 416, E_ITEM_IRON_HORSE_ARMOR = 417, diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index df8bb6bfa..ec5283774 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -399,8 +399,12 @@ char cItemHandler::GetMaxStackSize(void) switch (m_ItemType) { + case E_ITEM_ACACIA_DOOR: return 64; + case E_ITEM_ARMOR_STAND: return 16; case E_ITEM_ARROW: return 64; case E_ITEM_BAKED_POTATO: return 64; + case E_ITEM_BANNER: return 16; + case E_ITEM_BIRCH_DOOR: return 64; case E_ITEM_BLAZE_POWDER: return 64; case E_ITEM_BLAZE_ROD: return 64; case E_ITEM_BONE: return 64; @@ -411,7 +415,6 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_BREWING_STAND: return 64; case E_ITEM_BUCKET: return 16; case E_ITEM_CARROT: return 64; - case E_ITEM_CAKE: return 1; case E_ITEM_CAULDRON: return 64; case E_ITEM_CLAY: return 64; case E_ITEM_CLAY_BRICK: return 64; @@ -422,7 +425,9 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_COOKED_CHICKEN: return 64; case E_ITEM_COOKED_FISH: return 64; case E_ITEM_COOKED_PORKCHOP: return 64; + case E_ITEM_COOKED_MUTTON: return 64; case E_ITEM_COOKIE: return 64; + case E_ITEM_DARK_OAK_DOOR: return 64; case E_ITEM_DIAMOND: return 64; case E_ITEM_DYE: return 64; case E_ITEM_EGG: return 16; @@ -446,6 +451,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_GOLD_NUGGET: return 64; case E_ITEM_GUNPOWDER: return 64; case E_ITEM_HEAD: return 64; + case E_ITEM_JUNGLE_DOOR: return 64; case E_ITEM_IRON: return 64; case E_ITEM_ITEM_FRAME: return 64; case E_ITEM_LEATHER: return 64; @@ -459,11 +465,16 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_PAPER: return 64; case E_ITEM_POISONOUS_POTATO: return 64; case E_ITEM_POTATO: return 64; + case E_ITEM_PRISMARINE_CRYSTALS: return 64; + case E_ITEM_PRISMARINE_SHARD: return 64; case E_ITEM_PUMPKIN_PIE: return 64; case E_ITEM_PUMPKIN_SEEDS: return 64; + case E_ITEM_RABBITS_FOOT: return 64; + case E_ITEM_RABBIT_HIDE: return 64; case E_ITEM_RAW_BEEF: return 64; case E_ITEM_RAW_CHICKEN: return 64; case E_ITEM_RAW_FISH: return 64; + case E_ITEM_RAW_MUTTON: return 64; case E_ITEM_RAW_PORKCHOP: return 64; case E_ITEM_RED_APPLE: return 64; case E_ITEM_REDSTONE_DUST: return 64; @@ -475,6 +486,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_SNOWBALL: return 16; case E_ITEM_SPAWN_EGG: return 64; case E_ITEM_SPIDER_EYE: return 64; + case E_ITEM_SPRUCE_DOOR: return 64; case E_ITEM_STEAK: return 64; case E_ITEM_STICK: return 64; case E_ITEM_STRING: return 64; @@ -553,43 +565,49 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) switch (a_BlockType) { case E_BLOCK_ANVIL: - case E_BLOCK_ENCHANTMENT_TABLE: - case E_BLOCK_FURNACE: - case E_BLOCK_LIT_FURNACE: + case E_BLOCK_BRICK: + case E_BLOCK_CAULDRON: case E_BLOCK_COAL_ORE: - case E_BLOCK_STONE: case E_BLOCK_COBBLESTONE: - case E_BLOCK_END_STONE: - case E_BLOCK_MOSSY_COBBLESTONE: - case E_BLOCK_SANDSTONE_STAIRS: - case E_BLOCK_SANDSTONE: - case E_BLOCK_STONE_BRICKS: - case E_BLOCK_NETHER_BRICK: - case E_BLOCK_NETHERRACK: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_BRICK: case E_BLOCK_COBBLESTONE_STAIRS: case E_BLOCK_COBBLESTONE_WALL: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_CAULDRON: - case E_BLOCK_OBSIDIAN: case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_ENCHANTMENT_TABLE: + case E_BLOCK_END_STONE: + case E_BLOCK_FURNACE: case E_BLOCK_GOLD_BLOCK: case E_BLOCK_GOLD_ORE: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_EMERALD_ORE: case E_BLOCK_IRON_BLOCK: case E_BLOCK_IRON_ORE: - case E_BLOCK_LAPIS_ORE: + case E_BLOCK_IRON_TRAPDOOR: case E_BLOCK_LAPIS_BLOCK: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_LIT_FURNACE: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_FENCE: + case E_BLOCK_NETHERRACK: + case E_BLOCK_NEW_STONE_SLAB: + case E_BLOCK_OBSIDIAN: + case E_BLOCK_PACKED_ICE: + case E_BLOCK_PRISMARINE_BLOCK: + case E_BLOCK_RED_SANDSTONE: + case E_BLOCK_RED_SANDSTONE_STAIRS: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: case E_BLOCK_SNOW: + case E_BLOCK_STONE: + case E_BLOCK_STONE_BRICKS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_STONE_SLAB: case E_BLOCK_VINES: - case E_BLOCK_PACKED_ICE: { return false; } -- cgit v1.2.3 From 5cf114da39e49353b422ac72c96724d3f6ff758e Mon Sep 17 00:00:00 2001 From: Masy98 Date: Fri, 12 Sep 2014 17:01:03 +0200 Subject: Added Sea Lantern drops --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockSeaLantern.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/Blocks/BlockSeaLantern.h (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index a470e6b21..96ef3fbf8 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -67,6 +67,7 @@ #include "BlockTripwireHook.h" #include "BlockSand.h" #include "BlockSapling.h" +#include "BlockSeaLantern.h" #include "BlockSideways.h" #include "BlockSignPost.h" #include "BlockSlab.h" @@ -287,6 +288,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType); case E_BLOCK_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType); + case E_BLOCK_SEA_LANTERN: return new cBlockSeaLanternHandler (a_BlockType); case E_BLOCK_SIGN_POST: return new cBlockSignPostHandler (a_BlockType); case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType); diff --git a/src/Blocks/BlockSeaLantern.h b/src/Blocks/BlockSeaLantern.h new file mode 100644 index 000000000..a9259d1d6 --- /dev/null +++ b/src/Blocks/BlockSeaLantern.h @@ -0,0 +1,30 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSeaLanternHandler : + public cBlockHandler +{ +public: + cBlockSeaLanternHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + cFastRandom Random; + a_Pickups.push_back(cItem(E_ITEM_PRISMARINE_CRYSTALS, (char)(2 + Random.NextInt(2)), 0)); + } +} ; + + + + -- cgit v1.2.3 From 010ac1e5f7ae606c798fb280562700d1a0c8d978 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 18:12:42 +0200 Subject: Fixed block place sounds. --- src/BlockInfo.cpp | 26 +++++++++++++------------- src/ClientHandle.cpp | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 9ac66d35d..0324cabf5 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -590,7 +590,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_LEAVES ].m_PlaceSound = "dig.grass"; a_Info[E_BLOCK_SPONGE ].m_PlaceSound = "dig.grass"; - a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_LAPIS_ORE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_LAPIS_BLOCK ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_DISPENSER ].m_PlaceSound = "dig.stone"; @@ -647,7 +647,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_STONE_BUTTON ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_SNOW ].m_PlaceSound = "dig.snow"; - a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_SNOW_BLOCK ].m_PlaceSound = "dig.snow"; a_Info[E_BLOCK_CACTUS ].m_PlaceSound = "dig.cloth"; a_Info[E_BLOCK_CLAY ].m_PlaceSound = "dig.gravel"; @@ -657,20 +657,20 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_PUMPKIN ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_NETHERRACK ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_SOULSAND ].m_PlaceSound = "dig.sand"; - a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.glass"; - a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_JACK_O_LANTERN ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_CAKE ].m_PlaceSound = "dig.snow"; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_REDSTONE_REPEATER_ON ].m_PlaceSound = "dig.wood"; - a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_TRAPDOOR ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_SILVERFISH_EGG ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_STONE_BRICKS ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_IRON_BARS ].m_PlaceSound = "dig.metal"; - a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_MELON ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_PUMPKIN_STEM ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_MELON_STEM ].m_PlaceSound = "dig.wood"; @@ -687,12 +687,12 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BREWING_STAND ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_CAULDRON ].m_PlaceSound = "dig.stone"; - a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.glass"; - a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_END_STONE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_DRAGON_EGG ].m_PlaceSound = "dig.stone"; - a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.glass"; - a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.stone"; + a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_WOODEN_SLAB ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_COCOA_POD ].m_PlaceSound = "dig.wood"; @@ -712,7 +712,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_CARROTS ].m_PlaceSound = "dig.grass"; a_Info[E_BLOCK_POTATOES ].m_PlaceSound = "dig.grass"; a_Info[E_BLOCK_HEAD ].m_PlaceSound = "dig.stone"; - a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "dig.anvil"; + a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "random.anvil_land"; a_Info[E_BLOCK_TRAPPED_CHEST ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood"; @@ -727,7 +727,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_PlaceSound = "dig.metal"; a_Info[E_BLOCK_DROPPER ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_STAINED_CLAY ].m_PlaceSound = "dig.stone"; - a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_NEW_LEAVES ].m_PlaceSound = "dig.grass"; a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; @@ -736,7 +736,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth"; a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone"; - a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.glass"; + a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass"; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e2759dc6c..02c2f4c56 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1453,8 +1453,20 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e cChunkInterface ChunkInterface(World->GetChunkMap()); NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); - // Step sound with 0.8f pitch is used as block placement sound - World->BroadcastSoundEffect(cBlockInfo::GetPlaceSound(BlockType), (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.8f); + AString PlaceSound = cBlockInfo::GetPlaceSound(BlockType); + float Volume = 1.0f, Pitch = 0.8f; + if (PlaceSound == "dig.metal") + { + Pitch = 1.2f; + PlaceSound = "dig.stone"; + } + else if (PlaceSound == "random.anvil_land") + { + Volume = 0.65f; + } + + World->BroadcastSoundEffect(PlaceSound, (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, Volume, Pitch); + cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); } -- cgit v1.2.3 From 20f3757d54cb755365a1c2969bc879af372a3d27 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 18:14:32 +0200 Subject: Play placesound from the middle of the block. --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 02c2f4c56..859185412 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1465,7 +1465,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e Volume = 0.65f; } - World->BroadcastSoundEffect(PlaceSound, (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, Volume, Pitch); + World->BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch); cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); } -- cgit v1.2.3 From a40eb93c33b8e2e199471263760234585c6ecb95 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 18:15:49 +0200 Subject: Added hoe interact sound. --- src/Items/ItemHoe.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index 8d0b71478..a92337b62 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -25,6 +25,7 @@ public: if ((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); + a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f); a_Player->UseEquippedItem(); return true; } -- cgit v1.2.3 From 80b0631c43d2f0bb18fa4a10611d747a8f464462 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 18:21:11 +0200 Subject: Only place farmland if no block is upper than dirt/grass. --- src/Items/ItemHoe.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index a92337b62..5b2423949 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -20,9 +20,14 @@ public: virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { + if ((a_Dir == BLOCK_FACE_NONE) || (a_BlockY >= cChunkDef::Height)) + { + return false; + } BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + BLOCKTYPE UpperBlock = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); - if ((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) + if (IsBlockTypeOfDirt(Block) && (UpperBlock == E_BLOCK_AIR)) { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f); -- cgit v1.2.3 From fcf558173e3bb9b2213c610815f82088e7541a1e Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 19:07:20 +0200 Subject: Fixed farmland issues. --- src/Blocks/BlockBed.cpp | 2 +- src/Blocks/BlockDoor.cpp | 2 +- src/Blocks/BlockFarmland.h | 99 +++++++++++++++++++++++++-------------------- src/Blocks/BlockFire.h | 4 +- src/Blocks/BlockMobHead.h | 12 +++--- src/Blocks/BlockPiston.cpp | 2 +- src/Blocks/ChunkInterface.h | 4 +- src/ChunkMap.cpp | 6 +-- src/ChunkMap.h | 4 +- src/Items/ItemHoe.h | 2 +- src/World.cpp | 2 +- 11 files changed, 75 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index cd5783f58..cd1cc2a5f 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -15,7 +15,7 @@ void cBlockBedHandler::OnPlacedByPlayer( if (a_BlockMeta < 8) { Vector3i Direction = MetaDataToDirection(a_BlockMeta); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8); + a_ChunkInterface.SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8); } } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 1204debab..1a277f071 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -102,7 +102,7 @@ void cBlockDoorHandler::OnPlacedByPlayer( { a_TopBlockMeta = 9; } - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta); } diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h index bb624e54f..02a48a4af 100644 --- a/src/Blocks/BlockFarmland.h +++ b/src/Blocks/BlockFarmland.h @@ -28,49 +28,12 @@ public: virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { - bool Found = false; - - EMCSBiome Biome = a_Chunk.GetBiomeAt(a_RelX, a_RelZ); - if (a_Chunk.GetWorld()->IsWeatherWet() && !IsBiomeNoDownfall(Biome)) - { - // Rain hydrates farmland, too, except in Desert biomes. - Found = true; - } - else - { - // Search for water in a close proximity: - // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles - // TODO: Rewrite this to use the chunk and its neighbors directly - cBlockArea Area; - int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; - if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4)) - { - // Too close to the world edge, cannot check surroundings; don't tick at all - return; - } - - size_t NumBlocks = Area.GetBlockCount(); - BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); - for (size_t i = 0; i < NumBlocks; i++) - { - if (IsBlockWater(BlockTypes[i])) - { - Found = true; - break; - } - } // for i - BlockTypes[] - } - NIBBLETYPE BlockMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); - - if (Found) + + if (IsWaterInNear(a_Chunk, a_RelX, a_RelY, a_RelZ)) { - // Water was found, hydrate the block until hydration reaches 7: - if (BlockMeta < 7) - { - a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++BlockMeta); - } + // Water was found, set block meta to 7 + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, 7); return; } @@ -80,9 +43,10 @@ public: a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta); return; } - + // Farmland too dry. If nothing is growing on top, turn back to dirt: - switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)) + BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); + switch (UpperBlock) { case E_BLOCK_CROPS: case E_BLOCK_POTATOES: @@ -95,16 +59,63 @@ public: } default: { - a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0); break; } } } + virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + if (a_BlockY >= cChunkDef::Height) + { + return; + } + + BLOCKTYPE UpperBlock = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); + if (cBlockInfo::FullyOccupiesVoxel(UpperBlock)) + { + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0); + } + } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.Add(E_BLOCK_DIRT, 1, 0); // Reset meta } + + bool IsWaterInNear(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) + { + if (a_Chunk.GetWorld()->IsWeatherWetAt(a_RelX, a_RelZ)) + { + // Rain hydrates farmland, too, except in Desert biomes. + return true; + } + + // Search for water in a close proximity: + // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles + // TODO: Rewrite this to use the chunk and its neighbors directly + cBlockArea Area; + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4)) + { + // Too close to the world edge, cannot check surroundings + return false; + } + + size_t NumBlocks = Area.GetBlockCount(); + BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); + for (size_t i = 0; i < NumBlocks; i++) + { + if (IsBlockWater(BlockTypes[i])) + { + return true; + } + } // for i - BlockTypes[] + + return false; + } } ; diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index b6d1d95f2..07fcefe16 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -126,11 +126,11 @@ public: { if (Dir == 1) { - a_ChunkInterface.SetBlock(a_WorldInterface, Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir); + a_ChunkInterface.SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir); } else { - a_ChunkInterface.SetBlock(a_WorldInterface, X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir); + a_ChunkInterface.SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir); } } } diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index ff1ef97bf..b51155802 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -146,9 +146,9 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Block entities - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); // Spawn the wither: a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); @@ -176,9 +176,9 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Block entities - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); // Spawn the wither: a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 164967621..0169fb266 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -52,7 +52,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) { - a_ChunkInterface.SetBlock(a_WorldInterface, newX, newY, newZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); } } diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index dea9d7c7e..d5f1f1273 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -37,9 +37,9 @@ public: /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ - void SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) + void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 9c105c5af..e8728091f 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1287,12 +1287,12 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP -void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) +void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) { cChunkInterface ChunkInterface(this); if (a_BlockType == E_BLOCK_AIR) { - BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); + BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ); } int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; @@ -1305,7 +1305,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); } - BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 7354536d4..dfa1a57b4 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -151,8 +151,8 @@ public: NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ); void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta); - void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true); - void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR); + void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true); + void QueueSetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR); bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index 5b2423949..8e63536d4 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -27,7 +27,7 @@ public: BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); BLOCKTYPE UpperBlock = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); - if (IsBlockTypeOfDirt(Block) && (UpperBlock == E_BLOCK_AIR)) + if (((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) && (UpperBlock == E_BLOCK_AIR)) { a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f); diff --git a/src/World.cpp b/src/World.cpp index fdc0aebad..fe0be00ae 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1727,7 +1727,7 @@ bool cWorld::SetAreaBiome(const cCuboid & a_Area, EMCSBiome a_Biome) void cWorld::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) { - m_ChunkMap->SetBlock(*this, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_SendToClients); + m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_SendToClients); } -- cgit v1.2.3 From 96e03fc3ea9dd0a009f8e1f10fa364b2868c5d94 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 19:34:19 +0200 Subject: Added extra mushroom handler. --- src/Entities/Player.cpp | 7 ------ src/Items/ItemFood.h | 2 +- src/Items/ItemHandler.cpp | 8 +++++-- src/Items/ItemMushroomSoup.h | 53 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 src/Items/ItemMushroomSoup.h (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e1f9c30ea..ea795e346 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -627,13 +627,6 @@ void cPlayer::FinishEating(void) return; } ItemHandler->OnFoodEaten(m_World, this, &Item); - - // if the food is mushroom soup, return a bowl to the inventory - if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP) - { - GetInventory().RemoveOneEquippedItem(); - GetInventory().AddItem(cItem(E_ITEM_BOWL), true, true); - } } diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 9035344df..1af6e21e8 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -1,3 +1,4 @@ + #pragma once #include "ItemHandler.h" @@ -39,7 +40,6 @@ public: // Golden apple handled in ItemGoldenApple case E_ITEM_GOLDEN_CARROT: return FoodInfo(6, 14.4); case E_ITEM_MELON_SLICE: return FoodInfo(2, 1.2); - case E_ITEM_MUSHROOM_SOUP: return FoodInfo(6, 7.2); case E_ITEM_POISONOUS_POTATO: return FoodInfo(2, 1.2); // Potatoes handled in ItemSeeds case E_ITEM_PUMPKIN_PIE: return FoodInfo(8, 4.8); diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index e425be627..8dc346e53 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -33,6 +33,7 @@ #include "ItemLilypad.h" #include "ItemMap.h" #include "ItemMinecart.h" +#include "ItemMushroomSoup.h" #include "ItemNetherWart.h" #include "ItemPainting.h" #include "ItemPickaxe.h" @@ -125,6 +126,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType); case E_ITEM_MAP: return new cItemMapHandler(); case E_ITEM_MILK: return new cItemMilkHandler(); + case E_ITEM_MUSHROOM_SOUP: return new cItemMushroomSoupHandler(a_ItemType); case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType); case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType); case E_ITEM_PAINTING: return new cItemPaintingHandler(a_ItemType); @@ -216,7 +218,6 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_COOKIE: case E_ITEM_GOLDEN_CARROT: case E_ITEM_MELON_SLICE: - case E_ITEM_MUSHROOM_SOUP: case E_ITEM_MUTTON: case E_ITEM_POISONOUS_POTATO: case E_ITEM_PUMPKIN_PIE: @@ -634,7 +635,10 @@ bool cItemHandler::GetEatEffect(cEntityEffect::eType & a_EffectType, int & a_Eff bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { UNUSED(a_Item); - a_Player->GetInventory().RemoveOneEquippedItem(); + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + } FoodInfo Info = GetFoodInfo(); if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) diff --git a/src/Items/ItemMushroomSoup.h b/src/Items/ItemMushroomSoup.h new file mode 100644 index 000000000..dba313ec5 --- /dev/null +++ b/src/Items/ItemMushroomSoup.h @@ -0,0 +1,53 @@ + +#pragma once + +#include "ItemHandler.h" + + + + + +class cItemMushroomSoupHandler : + public cItemHandler +{ + typedef cItemHandler super; + +public: + cItemMushroomSoupHandler(int a_ItemType) + : super(a_ItemType) + { + } + + + virtual bool IsFood(void) override + { + return true; + } + + + virtual FoodInfo GetFoodInfo(void) override + { + return FoodInfo(6, 7.2); + } + + + virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override + { + if (!super::EatItem(a_Player, a_Item)) + { + return false; + } + + // Return a bowl to the inventory + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().AddItem(cItem(E_ITEM_BOWL), true, true); + } + return true; + } + +}; + + + + -- cgit v1.2.3 From d5306f265b817f516a4c9de59a6605bb7fee0ae6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 12 Sep 2014 19:38:00 +0200 Subject: Only drop flint or gravel, not both. --- src/Blocks/BlockGravel.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockGravel.h b/src/Blocks/BlockGravel.h index 3a9fbd170..d076306fb 100644 --- a/src/Blocks/BlockGravel.h +++ b/src/Blocks/BlockGravel.h @@ -18,13 +18,15 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.Add(E_BLOCK_GRAVEL, 1, 0); - cFastRandom Random; if (Random.NextInt(30) == 0) { a_Pickups.Add(E_ITEM_FLINT, 1, 0); } + else + { + a_Pickups.Add(E_BLOCK_GRAVEL, 1, 0); + } } } ; -- cgit v1.2.3 From 4019847857b7737be949904c545d904a98096441 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 12 Sep 2014 20:50:24 +0100 Subject: Fixed friction being applied whilst airborne Reported by tonibm9 in #1300. --- src/Entities/Entity.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 9bcdcffeb..6969501a3 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -941,19 +941,21 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) } NextSpeed.y += fallspeed; } - - // Friction - if (NextSpeed.SqrLength() > 0.0004f) + else { - NextSpeed.x *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.x) < 0.05) - { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) + // Friction on ground + if (NextSpeed.SqrLength() > 0.0004f) { - NextSpeed.z = 0; + NextSpeed.x *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.x) < 0.05) + { + NextSpeed.x = 0; + } + NextSpeed.z *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.z) < 0.05) + { + NextSpeed.z = 0; + } } } -- cgit v1.2.3 From 3e741134279e02d204a8d4638f2d46dfbf814d0c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 12 Sep 2014 23:18:02 +0100 Subject: Implemented Chest Minecarts --- src/BlockEntities/BlockEntityWithItems.h | 2 +- src/BlockEntities/ChestEntity.cpp | 1 - src/BlockEntities/DispenserEntity.cpp | 1 - src/BlockEntities/DropSpenserEntity.cpp | 1 - src/BlockEntities/DropperEntity.cpp | 1 - src/BlockEntities/EnderChestEntity.h | 2 +- src/BlockEntities/FurnaceEntity.cpp | 1 - src/Entities/Minecart.cpp | 41 +++++++++++++++---- src/Entities/Minecart.h | 40 +++++++++++++----- src/UI/SlotArea.cpp | 35 ++++++++++++++++ src/UI/SlotArea.h | 14 +++++++ src/UI/Window.cpp | 30 ++++++++++++++ src/UI/Window.h | 15 +++++++ src/UI/WindowOwner.h | 69 +------------------------------- src/WorldStorage/NBTChunkSerializer.cpp | 2 +- 15 files changed, 161 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index 5f1639d45..c19958e8d 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -23,7 +23,7 @@ class cBlockEntityWithItems : // tolua_end // tolua doesn't seem to support multiple inheritance? , public cItemGrid::cListener - , public cBlockEntityWindowOwner + , public cWindowOwner // tolua_begin { typedef cBlockEntity super; diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 21e1f6ba2..13831b64a 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -15,7 +15,6 @@ cChestEntity::cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_ super(a_Type, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), m_NumActivePlayers(0) { - cBlockEntityWindowOwner::SetBlockEntity(this); } diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index c02c68afa..649107dbb 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -17,7 +17,6 @@ cDispenserEntity::cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : super(E_BLOCK_DISPENSER, a_BlockX, a_BlockY, a_BlockZ, a_World) { - SetBlockEntity(this); // cBlockEntityWindowOwner } diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index dc38e3e9b..c11a8c796 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -19,7 +19,6 @@ cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int m_ShouldDropSpense(false), m_IsPowered(false) { - SetBlockEntity(this); // cBlockEntityWindowOwner } diff --git a/src/BlockEntities/DropperEntity.cpp b/src/BlockEntities/DropperEntity.cpp index 5d4a8ad97..8f9ef210d 100644 --- a/src/BlockEntities/DropperEntity.cpp +++ b/src/BlockEntities/DropperEntity.cpp @@ -15,7 +15,6 @@ cDropperEntity::cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : super(E_BLOCK_DROPPER, a_BlockX, a_BlockY, a_BlockZ, a_World) { - SetBlockEntity(this); // cBlockEntityWindowOwner } diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index ed178f6fc..0715e9a29 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -12,7 +12,7 @@ // tolua_begin class cEnderChestEntity : public cBlockEntity, - public cBlockEntityWindowOwner + public cWindowOwner { typedef cBlockEntity super; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index 72fd7f2b3..d2ffd643b 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -36,7 +36,6 @@ cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY m_LastProgressFuel(0), m_LastProgressCook(0) { - cBlockEntityWindowOwner::SetBlockEntity(this); m_Contents.AddListener(*this); } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 1501eea84..a3927298e 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1103,29 +1103,54 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player) // cMinecartWithChest: cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) : - super(mpChest, a_X, a_Y, a_Z) + super(mpChest, a_X, a_Y, a_Z), + m_Contents(ContentsWidth, ContentsHeight) { + m_Contents.AddListener(*this); } -void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item) +void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) { - ASSERT(a_Idx < ARRAYCOUNT(m_Items)); - - m_Items[a_Idx] = a_Item; + // If the window is not created, open it anew: + cWindow * Window = GetWindow(); + if (Window == NULL) + { + OpenNewWindow(); + Window = GetWindow(); + } + + // Open the window for the player: + if (Window != NULL) + { + if (a_Player.GetWindow() != Window) + { + a_Player.OpenWindow(Window); + } + } } -void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) +void cMinecartWithChest::OpenNewWindow() +{ + OpenWindow(new cMinecartWithChestWindow(this)); +} + + + + + +void cMinecartWithChest::Destroyed() { - // Show the chest UI window to the player - // TODO + cItems Pickups; + m_Contents.CopyToItems(Pickups); + GetWorld()->SpawnItemPickups(Pickups, GetPosX(), GetPosY() + 1, GetPosZ(), 4); } diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 410d3c77d..f77a171ba 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -10,6 +10,7 @@ #pragma once #include "Entity.h" +#include "../UI/WindowOwner.h" @@ -108,27 +109,46 @@ protected: class cMinecartWithChest : - public cMinecart + public cMinecart, + public cItemGrid::cListener, + public cWindowOwner { typedef cMinecart super; public: CLASS_PROTODEF(cMinecartWithChest) - /// Number of item slots in the chest - static const int NumSlots = 9 * 3; - cMinecartWithChest(double a_X, double a_Y, double a_Z); + + enum + { + ContentsHeight = 3, + ContentsWidth = 9, + }; - const cItem & GetSlot(int a_Idx) const { return m_Items[a_Idx]; } - cItem & GetSlot(int a_Idx) { return m_Items[a_Idx]; } - - void SetSlot(size_t a_Idx, const cItem & a_Item); + const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } + void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } protected: + cItemGrid m_Contents; + void OpenNewWindow(void); + virtual void Destroyed() override; - /// The chest contents: - cItem m_Items[NumSlots]; + // cItemGrid::cListener overrides: + virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) + { + UNUSED(a_SlotNum); + ASSERT(a_Grid == &m_Contents); + if (m_World != NULL) + { + if (GetWindow() != NULL) + { + GetWindow()->BroadcastWholeWindow(); + } + + m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); + } + } // cEntity overrides: virtual void OnRightClicked(cPlayer & a_Player) override; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index b4facb2d3..999bed989 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -10,6 +10,7 @@ #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/FurnaceEntity.h" +#include "../Entities/Minecart.h" #include "../Items/ItemHandler.h" #include "Window.h" #include "../CraftingRecipes.h" @@ -1919,6 +1920,40 @@ void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Playe +//////////////////////////////////////////////////////////////////////////////// +// cSlotAreaMinecartWithChest: + +cSlotAreaMinecartWithChest::cSlotAreaMinecartWithChest(cMinecartWithChest * a_Chest, cWindow & a_ParentWindow) : + cSlotArea(27, a_ParentWindow), + m_Chest(a_Chest) +{ +} + + + + + +const cItem * cSlotAreaMinecartWithChest::GetSlot(int a_SlotNum, cPlayer & a_Player) const +{ + // a_SlotNum ranges from 0 to 26, use that to index the minecart chest entity's inventory directly: + UNUSED(a_Player); + return &(m_Chest->GetSlot(a_SlotNum)); +} + + + + + +void cSlotAreaMinecartWithChest::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) +{ + UNUSED(a_Player); + m_Chest->SetSlot(a_SlotNum, a_Item); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cSlotAreaInventoryBase: diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 6bbc87b76..0a35527d1 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -20,6 +20,7 @@ class cChestEntity; class cDropSpenserEntity; class cEnderChestEntity; class cFurnaceEntity; +class cMinecartWithChest; class cCraftingRecipe; class cEnchantingWindow; class cWorld; @@ -455,3 +456,16 @@ protected: + +class cSlotAreaMinecartWithChest : + public cSlotArea +{ +public: + cSlotAreaMinecartWithChest(cMinecartWithChest * a_ChestCart, cWindow & a_ParentWindow); + + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; + virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; + +protected: + cMinecartWithChest * m_Chest; +}; \ No newline at end of file diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 66900269f..fd80a017d 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -14,6 +14,7 @@ #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/HopperEntity.h" +#include "../Entities/Minecart.h" #include "../Root.h" #include "../Bindings/PluginManager.h" @@ -1047,6 +1048,34 @@ cChestWindow::~cChestWindow() +//////////////////////////////////////////////////////////////////////////////// +// cMinecartWithChestWindow: + +cMinecartWithChestWindow::cMinecartWithChestWindow(cMinecartWithChest * a_ChestCart) : + cWindow(wtChest, "Minecart with Chest"), + m_ChestCart(a_ChestCart) +{ + m_ShouldDistributeToHotbarFirst = false; + m_SlotAreas.push_back(new cSlotAreaMinecartWithChest(a_ChestCart, *this)); + m_SlotAreas.push_back(new cSlotAreaInventory(*this)); + m_SlotAreas.push_back(new cSlotAreaHotBar(*this)); + + a_ChestCart->GetWorld()->BroadcastSoundEffect("random.chestopen", a_ChestCart->GetPosX(), a_ChestCart->GetPosY(), a_ChestCart->GetPosZ(), 1, 1); +} + + + + + +cMinecartWithChestWindow::~cMinecartWithChestWindow() +{ + m_ChestCart->GetWorld()->BroadcastSoundEffect("random.chestclosed", m_ChestCart->GetPosX(), m_ChestCart->GetPosY(), m_ChestCart->GetPosZ(), 1, 1); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cDropSpenserWindow: @@ -1073,6 +1102,7 @@ cEnderChestWindow::cEnderChestWindow(cEnderChestEntity * a_EnderChest) : m_BlockY(a_EnderChest->GetPosY()), m_BlockZ(a_EnderChest->GetPosZ()) { + m_ShouldDistributeToHotbarFirst = false; m_SlotAreas.push_back(new cSlotAreaEnderChest(a_EnderChest, *this)); m_SlotAreas.push_back(new cSlotAreaInventory(*this)); m_SlotAreas.push_back(new cSlotAreaHotBar(*this)); diff --git a/src/UI/Window.h b/src/UI/Window.h index 3d860407f..f47cf4b99 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -23,6 +23,7 @@ class cDropSpenserEntity; class cEnderChestEntity; class cFurnaceEntity; class cHopperEntity; +class cMinecartWithChest; class cBeaconEntity; class cSlotArea; class cSlotAreaAnvil; @@ -360,6 +361,20 @@ protected: +class cMinecartWithChestWindow : + public cWindow +{ +public: + cMinecartWithChestWindow(cMinecartWithChest * a_ChestCart); + ~cMinecartWithChestWindow(); +private: + cMinecartWithChest * m_ChestCart; +}; + + + + + class cEnderChestWindow : public cWindow { diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h index 7a7941e37..a8be3e6cb 100644 --- a/src/UI/WindowOwner.h +++ b/src/UI/WindowOwner.h @@ -52,77 +52,10 @@ public: { return m_Window; } - - /// Returns the block position at which the element owning the window is - virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) = 0; private: cWindow * m_Window; -} ; - - - - - -/** -Window owner that is associated with a block entity (chest, furnace, ...) -*/ -class cBlockEntityWindowOwner : - public cWindowOwner -{ -public: - cBlockEntityWindowOwner(void) : - m_BlockEntity(NULL) - { - } - - void SetBlockEntity(cBlockEntity * a_BlockEntity) - { - m_BlockEntity = a_BlockEntity; - } - - virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) override - { - a_BlockX = m_BlockEntity->GetPosX(); - a_BlockY = m_BlockEntity->GetPosY(); - a_BlockZ = m_BlockEntity->GetPosZ(); - } - -private: - cBlockEntity * m_BlockEntity; -} ; - - - - - -/** -Window owner that is associated with an entity (chest minecart) -*/ -class cEntityWindowOwner : - public cWindowOwner -{ -public: - cEntityWindowOwner(void) : - m_Entity(NULL) - { - } - - void SetEntity(cEntity * a_Entity) - { - m_Entity = a_Entity; - } - - virtual void GetBlockPos(int & a_BlockX, int & a_BlockY, int & a_BlockZ) override - { - a_BlockX = (int)floor(m_Entity->GetPosX() + 0.5); - a_BlockY = (int)floor(m_Entity->GetPosY() + 0.5); - a_BlockZ = (int)floor(m_Entity->GetPosZ() + 0.5); - } - -private: - cEntity * m_Entity; -} ; +}; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 68e541eba..963e016d6 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -738,7 +738,7 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame) void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) { m_Writer.BeginList("Items", TAG_Compound); - for (int i = 0; i < cMinecartWithChest::NumSlots; i++) + for (int i = 0; i < cMinecartWithChest::ContentsHeight * cMinecartWithChest::ContentsWidth; i++) { const cItem & Item = a_Minecart->GetSlot(i); if (Item.IsEmpty()) -- cgit v1.2.3 From b462416e1fef58b3ddccc92f3dfe613fc27d5483 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 13 Sep 2014 02:20:04 +0200 Subject: 1.8: Fixed maps. --- src/ClientHandle.cpp | 8 ++++---- src/ClientHandle.h | 4 ++-- src/Map.cpp | 8 ++++---- src/Protocol/Protocol.h | 4 ++-- src/Protocol/Protocol125.cpp | 4 ++-- src/Protocol/Protocol125.h | 4 ++-- src/Protocol/Protocol17x.cpp | 5 ++--- src/Protocol/Protocol17x.h | 4 ++-- src/Protocol/Protocol18x.cpp | 31 +++++++++++++++---------------- src/Protocol/Protocol18x.h | 4 ++-- src/Protocol/ProtocolRecognizer.cpp | 8 ++++---- src/Protocol/ProtocolRecognizer.h | 4 ++-- 12 files changed, 43 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 9b6151656..fa27664ef 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2337,18 +2337,18 @@ void cClientHandle::SendInventorySlot(char a_WindowID, short a_SlotNum, const cI -void cClientHandle::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +void cClientHandle::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { - m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length); + m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length, m_Scale); } -void cClientHandle::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +void cClientHandle::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { - m_Protocol->SendMapDecorators(a_ID, a_Decorators); + m_Protocol->SendMapDecorators(a_ID, a_Decorators, m_Scale); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7c5597b8b..27bfc756c 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -148,8 +148,8 @@ public: void SendGameMode (eGameMode a_GameMode); void SendHealth (void); void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item); - void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length); - void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators); + void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale); + void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale); void SendMapInfo (int a_ID, unsigned int a_Scale); void SendPaintingSpawn (const cPainting & a_Painting); void SendPickupSpawn (const cPickup & a_Pickup); diff --git a/src/Map.cpp b/src/Map.cpp index 8f205a606..c106ccd83 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -432,7 +432,7 @@ void cMap::StreamNext(cMapClient & a_Client) // This is dangerous as the player object may have been destroyed before the decorator is erased from the list UpdateDecorators(); - Handle->SendMapDecorators(m_ID, m_Decorators); + Handle->SendMapDecorators(m_ID, m_Decorators, m_Scale); a_Client.m_NextDecoratorUpdate = 0; } @@ -444,7 +444,7 @@ void cMap::StreamNext(cMapClient & a_Client) const Byte * Colors = &m_Data[Y * m_Height]; - Handle->SendMapColumn(m_ID, Y, 0, Colors, m_Height); + Handle->SendMapColumn(m_ID, Y, 0, Colors, m_Height, m_Scale); } } @@ -595,10 +595,10 @@ void cMap::SendTo(cClientHandle & a_Client) { const Byte* Colors = &m_Data[i * m_Height]; - a_Client.SendMapColumn(m_ID, i, 0, Colors, m_Height); + a_Client.SendMapColumn(m_ID, i, 0, Colors, m_Height, m_Scale); } - a_Client.SendMapDecorators(m_ID, m_Decorators); + a_Client.SendMapDecorators(m_ID, m_Decorators, m_Scale); } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8c9fadd1a..eceec4974 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -86,8 +86,8 @@ public: virtual void SendKeepAlive (int a_PingID) = 0; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0; virtual void SendLoginSuccess (void) = 0; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) = 0; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) = 0; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) = 0; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) = 0; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) = 0; virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0; virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 0c481024e..c785553a5 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -608,7 +608,7 @@ void cProtocol125::SendLoginSuccess(void) -void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { cCSLock Lock(m_CSPacket); @@ -630,7 +630,7 @@ void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo -void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { cCSLock Lock(m_CSPacket); diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 262e1818d..4e140331a 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -57,8 +57,8 @@ public: virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index eaf226841..f36ec5b49 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -715,7 +715,7 @@ void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { ASSERT(m_State == 3); // In game mode? @@ -737,7 +737,7 @@ void cProtocol172::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo -void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { ASSERT(m_State == 3); // In game mode? @@ -775,7 +775,6 @@ void cProtocol172::SendMapInfo(int a_ID, unsigned int a_Scale) - void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 60088a1b8..b37de1527 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -94,8 +94,8 @@ public: virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 735700dda..b3cdcc7bc 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -728,18 +728,21 @@ void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol180::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +void cProtocol180::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x34); Pkt.WriteVarInt(a_ID); - Pkt.WriteShort (3 + a_Length); + Pkt.WriteByte(m_Scale); - Pkt.WriteByte(0); + Pkt.WriteVarInt(0); + Pkt.WriteByte(1); + Pkt.WriteByte(a_Length); Pkt.WriteByte(a_X); Pkt.WriteByte(a_Y); - + + Pkt.WriteVarInt(a_Length); for (unsigned int i = 0; i < a_Length; ++i) { Pkt.WriteByte(a_Colors[i]); @@ -750,22 +753,23 @@ void cProtocol180::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo -void cProtocol180::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +void cProtocol180::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x34); Pkt.WriteVarInt(a_ID); - Pkt.WriteShort ((short)(1 + (3 * a_Decorators.size()))); + Pkt.WriteByte(m_Scale); + Pkt.WriteVarInt(a_Decorators.size()); - Pkt.WriteByte(1); - for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it) { Pkt.WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf)); Pkt.WriteByte(it->GetPixelX()); Pkt.WriteByte(it->GetPixelZ()); } + + Pkt.WriteByte(0); } @@ -774,21 +778,16 @@ void cProtocol180::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor void cProtocol180::SendMapInfo(int a_ID, unsigned int a_Scale) { - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, 0x34); - Pkt.WriteVarInt(a_ID); - Pkt.WriteShort (2); + UNUSED(a_ID); + UNUSED(a_Scale); - Pkt.WriteByte(2); - Pkt.WriteByte(a_Scale); + // This packet was removed in 1.8 } - void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) { ASSERT(m_State == 3); // In game mode? diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 97ab3e93c..70696d32d 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -89,8 +89,8 @@ public: virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 28b2b9c4b..611ef6ce0 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -411,20 +411,20 @@ void cProtocolRecognizer::SendLoginSuccess(void) -void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) +void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) { ASSERT(m_Protocol != NULL); - m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length); + m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length, m_Scale); } -void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators) +void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) { ASSERT(m_Protocol != NULL); - m_Protocol->SendMapDecorators(a_ID, a_Decorators); + m_Protocol->SendMapDecorators(a_ID, a_Decorators, m_Scale); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index f73b0b92a..9a0169b97 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -93,8 +93,8 @@ public: virtual void SendKeepAlive (int a_PingID) override; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; -- cgit v1.2.3 From a8c7dadfd72e95e55a2773a69c796c087f95cfbb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 13 Sep 2014 11:14:17 +0100 Subject: Added newlines --- src/UI/SlotArea.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 0a35527d1..35743908a 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -468,4 +468,8 @@ public: protected: cMinecartWithChest * m_Chest; -}; \ No newline at end of file +}; + + + + -- cgit v1.2.3 From bc37b895bca7591e5fc9945bea54d9cac6a1deeb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 13 Sep 2014 11:15:16 +0100 Subject: e.t.c. -> etc. etcetera, not egg tray conglomerate :P --- src/UI/SlotArea.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 35743908a..1eeeb9836 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -449,7 +449,7 @@ protected: // cItemGrid::cListener overrides: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; - /// Called after an item has been smelted to handle statistics e.t.c. + /// Called after an item has been smelted to handle statistics etc. void HandleSmeltItem(const cItem & a_Result, cPlayer & a_Player); } ; -- cgit v1.2.3 From f323955099eb19f5ff3969d09db05f58a842b95b Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 13 Sep 2014 20:27:10 +0200 Subject: Moved chat json creating to the CompositeChat class. --- src/CompositeChat.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++ src/CompositeChat.h | 6 ++ src/Protocol/Protocol17x.cpp | 173 +---------------------------------------- src/Protocol/Protocol17x.h | 4 +- src/Protocol/Protocol18x.cpp | 173 +---------------------------------------- src/Protocol/Protocol18x.h | 4 +- 6 files changed, 192 insertions(+), 346 deletions(-) (limited to 'src') diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 0d339021e..d1eb0b852 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "CompositeChat.h" +#include "ClientHandle.h" @@ -399,6 +400,183 @@ void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) +AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const +{ + Json::Value msg; + msg["text"] = cClientHandle::FormatMessageType(a_ShouldUseChatPrefixes, GetMessageType(), GetAdditionalMessageTypeData()); // The client crashes without this field being present + const cCompositeChat::cParts & Parts = GetParts(); + for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) + { + Json::Value Part; + switch ((*itr)->m_PartType) + { + case cCompositeChat::ptText: + { + Part["text"] = (*itr)->m_Text; + AddChatPartStyle(Part, (*itr)->m_Style); + break; + } + + case cCompositeChat::ptClientTranslated: + { + const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; + Part["translate"] = p.m_Text; + Json::Value With; + for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) + { + With.append(*itrW); + } + if (!p.m_Parameters.empty()) + { + Part["with"] = With; + } + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptUrl: + { + const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Url; + Url["action"] = "open_url"; + Url["value"] = p.m_Url; + Part["clickEvent"] = Url; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptSuggestCommand: + case cCompositeChat::ptRunCommand: + { + const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; + Part["text"] = p.m_Text; + Json::Value Cmd; + Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; + Cmd["value"] = p.m_Command; + Part["clickEvent"] = Cmd; + AddChatPartStyle(Part, p.m_Style); + break; + } + + case cCompositeChat::ptShowAchievement: + { + const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; + Part["translate"] = "chat.type.achievement"; + + Json::Value Ach; + Ach["action"] = "show_achievement"; + Ach["value"] = p.m_Text; + + Json::Value AchColourAndName; + AchColourAndName["color"] = "green"; + AchColourAndName["translate"] = p.m_Text; + AchColourAndName["hoverEvent"] = Ach; + + Json::Value Extra; + Extra.append(AchColourAndName); + + Json::Value Name; + Name["text"] = p.m_PlayerName; + + Json::Value With; + With.append(Name); + With.append(Extra); + + Part["with"] = With; + AddChatPartStyle(Part, p.m_Style); + break; + } + } + msg["extra"].append(Part); + } // for itr - Parts[] + + return msg.toStyledString(); +} + + + + + +void cCompositeChat::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const +{ + size_t len = a_PartStyle.length(); + for (size_t i = 0; i < len; i++) + { + switch (a_PartStyle[i]) + { + case 'b': + { + // bold + a_Value["bold"] = Json::Value(true); + break; + } + + case 'i': + { + // italic + a_Value["italic"] = Json::Value(true); + break; + } + + case 'u': + { + // Underlined + a_Value["underlined"] = Json::Value(true); + break; + } + + case 's': + { + // strikethrough + a_Value["strikethrough"] = Json::Value(true); + break; + } + + case 'o': + { + // obfuscated + a_Value["obfuscated"] = Json::Value(true); + break; + } + + case '@': + { + // Color, specified by the next char: + i++; + if (i >= len) + { + // String too short, didn't contain a color + break; + } + switch (a_PartStyle[i]) + { + case '0': a_Value["color"] = Json::Value("black"); break; + case '1': a_Value["color"] = Json::Value("dark_blue"); break; + case '2': a_Value["color"] = Json::Value("dark_green"); break; + case '3': a_Value["color"] = Json::Value("dark_aqua"); break; + case '4': a_Value["color"] = Json::Value("dark_red"); break; + case '5': a_Value["color"] = Json::Value("dark_purple"); break; + case '6': a_Value["color"] = Json::Value("gold"); break; + case '7': a_Value["color"] = Json::Value("gray"); break; + case '8': a_Value["color"] = Json::Value("dark_gray"); break; + case '9': a_Value["color"] = Json::Value("blue"); break; + case 'a': a_Value["color"] = Json::Value("green"); break; + case 'b': a_Value["color"] = Json::Value("aqua"); break; + case 'c': a_Value["color"] = Json::Value("red"); break; + case 'd': a_Value["color"] = Json::Value("light_purple"); break; + case 'e': a_Value["color"] = Json::Value("yellow"); break; + case 'f': a_Value["color"] = Json::Value("white"); break; + } // switch (color) + } // case '@' + } // switch (Style[i]) + } // for i - a_PartStyle[] +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cCompositeChat::cBasePart: diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 2dc21b98f..369eed196 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -4,6 +4,7 @@ // Declares the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd) #include "Defines.h" +#include "json/json.h" @@ -189,6 +190,8 @@ public: Used for older protocols that don't support composite chat and for console-logging. */ AString ExtractText(void) const; + + AString CreateJsonString(bool a_ShouldUseChatPrefixes = true) const; // tolua_end @@ -197,6 +200,9 @@ public: /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + + /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */ + void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const; protected: /** All the parts that */ diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f36ec5b49..f51f15ec2 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -239,101 +239,13 @@ void cProtocol172::SendChat(const AString & a_Message) void cProtocol172::SendChat(const cCompositeChat & a_Message) { ASSERT(m_State == 3); // In game mode? - - // Compose the complete Json string to send: - Json::Value msg; + cWorld * World = m_Client->GetPlayer()->GetWorld(); - msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present - const cCompositeChat::cParts & Parts = a_Message.GetParts(); - for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) - { - Json::Value Part; - switch ((*itr)->m_PartType) - { - case cCompositeChat::ptText: - { - Part["text"] = (*itr)->m_Text; - AddChatPartStyle(Part, (*itr)->m_Style); - break; - } - - case cCompositeChat::ptClientTranslated: - { - const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; - Part["translate"] = p.m_Text; - Json::Value With; - for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) - { - With.append(*itrW); - } - if (!p.m_Parameters.empty()) - { - Part["with"] = With; - } - AddChatPartStyle(Part, p.m_Style); - break; - } - - case cCompositeChat::ptUrl: - { - const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Url; - Url["action"] = "open_url"; - Url["value"] = p.m_Url; - Part["clickEvent"] = Url; - AddChatPartStyle(Part, p.m_Style); - break; - } - - case cCompositeChat::ptSuggestCommand: - case cCompositeChat::ptRunCommand: - { - const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Cmd; - Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; - Cmd["value"] = p.m_Command; - Part["clickEvent"] = Cmd; - AddChatPartStyle(Part, p.m_Style); - break; - } + bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes(); - case cCompositeChat::ptShowAchievement: - { - const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; - Part["translate"] = "chat.type.achievement"; - - Json::Value Ach; - Ach["action"] = "show_achievement"; - Ach["value"] = p.m_Text; - - Json::Value AchColourAndName; - AchColourAndName["color"] = "green"; - AchColourAndName["translate"] = p.m_Text; - AchColourAndName["hoverEvent"] = Ach; - - Json::Value Extra; - Extra.append(AchColourAndName); - - Json::Value Name; - Name["text"] = p.m_PlayerName; - - Json::Value With; - With.append(Name); - With.append(Extra); - - Part["with"] = With; - AddChatPartStyle(Part, p.m_Style); - break; - } - } - msg["extra"].append(Part); - } // for itr - Parts[] - // Send the message to the client: cPacketizer Pkt(*this, 0x02); - Pkt.WriteString(msg.toStyledString()); + Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes)); } @@ -2427,85 +2339,6 @@ void cProtocol172::StartEncryption(const Byte * a_Key) -void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) -{ - size_t len = a_PartStyle.length(); - for (size_t i = 0; i < len; i++) - { - switch (a_PartStyle[i]) - { - case 'b': - { - // bold - a_Value["bold"] = Json::Value(true); - break; - } - - case 'i': - { - // italic - a_Value["italic"] = Json::Value(true); - break; - } - - case 'u': - { - // Underlined - a_Value["underlined"] = Json::Value(true); - break; - } - - case 's': - { - // strikethrough - a_Value["strikethrough"] = Json::Value(true); - break; - } - - case 'o': - { - // obfuscated - a_Value["obfuscated"] = Json::Value(true); - break; - } - - case '@': - { - // Color, specified by the next char: - i++; - if (i >= len) - { - // String too short, didn't contain a color - break; - } - switch (a_PartStyle[i]) - { - case '0': a_Value["color"] = Json::Value("black"); break; - case '1': a_Value["color"] = Json::Value("dark_blue"); break; - case '2': a_Value["color"] = Json::Value("dark_green"); break; - case '3': a_Value["color"] = Json::Value("dark_aqua"); break; - case '4': a_Value["color"] = Json::Value("dark_red"); break; - case '5': a_Value["color"] = Json::Value("dark_purple"); break; - case '6': a_Value["color"] = Json::Value("gold"); break; - case '7': a_Value["color"] = Json::Value("gray"); break; - case '8': a_Value["color"] = Json::Value("dark_gray"); break; - case '9': a_Value["color"] = Json::Value("blue"); break; - case 'a': a_Value["color"] = Json::Value("green"); break; - case 'b': a_Value["color"] = Json::Value("aqua"); break; - case 'c': a_Value["color"] = Json::Value("red"); break; - case 'd': a_Value["color"] = Json::Value("light_purple"); break; - case 'e': a_Value["color"] = Json::Value("yellow"); break; - case 'f': a_Value["color"] = Json::Value("white"); break; - } // switch (color) - } // case '@' - } // switch (Style[i]) - } // for i - a_PartStyle[] -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cProtocol172::cPacketizer: diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index b37de1527..6668d0a87 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -307,9 +307,7 @@ protected: void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); void StartEncryption(const Byte * a_Key); - - /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */ - void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle); + } ; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index b3cdcc7bc..5023acf2d 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -231,101 +231,13 @@ void cProtocol180::SendChat(const AString & a_Message) void cProtocol180::SendChat(const cCompositeChat & a_Message) { ASSERT(m_State == 3); // In game mode? - - // Compose the complete Json string to send: - Json::Value msg; + cWorld * World = m_Client->GetPlayer()->GetWorld(); - msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present - const cCompositeChat::cParts & Parts = a_Message.GetParts(); - for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) - { - Json::Value Part; - switch ((*itr)->m_PartType) - { - case cCompositeChat::ptText: - { - Part["text"] = (*itr)->m_Text; - AddChatPartStyle(Part, (*itr)->m_Style); - break; - } - - case cCompositeChat::ptClientTranslated: - { - const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr; - Part["translate"] = p.m_Text; - Json::Value With; - for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr) - { - With.append(*itrW); - } - if (!p.m_Parameters.empty()) - { - Part["with"] = With; - } - AddChatPartStyle(Part, p.m_Style); - break; - } - - case cCompositeChat::ptUrl: - { - const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Url; - Url["action"] = "open_url"; - Url["value"] = p.m_Url; - Part["clickEvent"] = Url; - AddChatPartStyle(Part, p.m_Style); - break; - } - - case cCompositeChat::ptSuggestCommand: - case cCompositeChat::ptRunCommand: - { - const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr; - Part["text"] = p.m_Text; - Json::Value Cmd; - Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command"; - Cmd["value"] = p.m_Command; - Part["clickEvent"] = Cmd; - AddChatPartStyle(Part, p.m_Style); - break; - } + bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes(); - case cCompositeChat::ptShowAchievement: - { - const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; - Part["translate"] = "chat.type.achievement"; - - Json::Value Ach; - Ach["action"] = "show_achievement"; - Ach["value"] = p.m_Text; - - Json::Value AchColourAndName; - AchColourAndName["color"] = "green"; - AchColourAndName["translate"] = p.m_Text; - AchColourAndName["hoverEvent"] = Ach; - - Json::Value Extra; - Extra.append(AchColourAndName); - - Json::Value Name; - Name["text"] = p.m_PlayerName; - - Json::Value With; - With.append(Name); - With.append(Extra); - - Part["with"] = With; - AddChatPartStyle(Part, p.m_Style); - break; - } - } - msg["extra"].append(Part); - } // for itr - Parts[] - // Send the message to the client: cPacketizer Pkt(*this, 0x02); - Pkt.WriteString(msg.toStyledString()); + Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes)); Pkt.WriteChar(0); } @@ -2693,85 +2605,6 @@ void cProtocol180::StartEncryption(const Byte * a_Key) -void cProtocol180::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) -{ - size_t len = a_PartStyle.length(); - for (size_t i = 0; i < len; i++) - { - switch (a_PartStyle[i]) - { - case 'b': - { - // bold - a_Value["bold"] = Json::Value(true); - break; - } - - case 'i': - { - // italic - a_Value["italic"] = Json::Value(true); - break; - } - - case 'u': - { - // Underlined - a_Value["underlined"] = Json::Value(true); - break; - } - - case 's': - { - // strikethrough - a_Value["strikethrough"] = Json::Value(true); - break; - } - - case 'o': - { - // obfuscated - a_Value["obfuscated"] = Json::Value(true); - break; - } - - case '@': - { - // Color, specified by the next char: - i++; - if (i >= len) - { - // String too short, didn't contain a color - break; - } - switch (a_PartStyle[i]) - { - case '0': a_Value["color"] = Json::Value("black"); break; - case '1': a_Value["color"] = Json::Value("dark_blue"); break; - case '2': a_Value["color"] = Json::Value("dark_green"); break; - case '3': a_Value["color"] = Json::Value("dark_aqua"); break; - case '4': a_Value["color"] = Json::Value("dark_red"); break; - case '5': a_Value["color"] = Json::Value("dark_purple"); break; - case '6': a_Value["color"] = Json::Value("gold"); break; - case '7': a_Value["color"] = Json::Value("gray"); break; - case '8': a_Value["color"] = Json::Value("dark_gray"); break; - case '9': a_Value["color"] = Json::Value("blue"); break; - case 'a': a_Value["color"] = Json::Value("green"); break; - case 'b': a_Value["color"] = Json::Value("aqua"); break; - case 'c': a_Value["color"] = Json::Value("red"); break; - case 'd': a_Value["color"] = Json::Value("light_purple"); break; - case 'e': a_Value["color"] = Json::Value("yellow"); break; - case 'f': a_Value["color"] = Json::Value("white"); break; - } // switch (color) - } // case '@' - } // switch (Style[i]) - } // for i - a_PartStyle[] -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cProtocol180::cPacketizer: diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 70696d32d..7ba2b92cd 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -324,9 +324,7 @@ protected: void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); void StartEncryption(const Byte * a_Key); - - /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */ - void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle); + } ; -- cgit v1.2.3 From 94d562502dd7abf65fa471666c46568609db1e7e Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 13 Sep 2014 21:48:16 +0200 Subject: 1.8: Updated scoreboard packets. --- src/Protocol/Protocol18x.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 5023acf2d..54dea049b 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1035,8 +1035,12 @@ void cProtocol180::SendScoreboardObjective(const AString & a_Name, const AString cPacketizer Pkt(*this, 0x3b); Pkt.WriteString(a_Name); - Pkt.WriteString(a_DisplayName); Pkt.WriteByte(a_Mode); + if ((a_Mode == 0) || (a_Mode == 2)) + { + Pkt.WriteString(a_DisplayName); + Pkt.WriteString("integer"); + } } @@ -1050,11 +1054,11 @@ void cProtocol180::SendScoreUpdate(const AString & a_Objective, const AString & cPacketizer Pkt(*this, 0x3c); Pkt.WriteString(a_Player); Pkt.WriteByte(a_Mode); + Pkt.WriteString(a_Objective); if (a_Mode != 1) { - Pkt.WriteString(a_Objective); - Pkt.WriteInt((int) a_Score); + Pkt.WriteVarInt((UInt32) a_Score); } } -- cgit v1.2.3 From 52d86728e69023f8d70c84f019335b713453aa2d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 13 Sep 2014 22:49:05 +0100 Subject: Entities experience water resistance --- src/Entities/Entity.cpp | 41 +++++++++++++++++++++++++---------------- src/Entities/Entity.h | 6 ++++++ 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 6969501a3..42b207c48 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -927,12 +927,13 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) float fallspeed; if (IsBlockWater(BlockIn)) { - fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water. + fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water + ApplyFriction(NextSpeed, 0.7, a_Dt); } else if (BlockIn == E_BLOCK_COBWEB) { NextSpeed.y *= 0.05; // Reduce overall falling speed - fallspeed = 0; // No falling. + fallspeed = 0; // No falling } else { @@ -943,20 +944,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) } else { - // Friction on ground - if (NextSpeed.SqrLength() > 0.0004f) - { - NextSpeed.x *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.x) < 0.05) - { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) - { - NextSpeed.z = 0; - } - } + ApplyFriction(NextSpeed, 0.7, a_Dt); } // Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we @@ -1062,6 +1050,27 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) +void cEntity::ApplyFriction(Vector3d & a_Speed, double a_SlowdownMultiplier, float a_Dt) +{ + if (a_Speed.SqrLength() > 0.0004f) + { + a_Speed.x *= a_SlowdownMultiplier / (1 + a_Dt); + if (fabs(a_Speed.x) < 0.05) + { + a_Speed.x = 0; + } + a_Speed.z *= a_SlowdownMultiplier / (1 + a_Dt); + if (fabs(a_Speed.z) < 0.05) + { + a_Speed.z = 0; + } + } +} + + + + + void cEntity::TickBurning(cChunk & a_Chunk) { // Remember the current burning state: diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b9c280b6b..6bc070dcc 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -535,6 +535,12 @@ protected: virtual void Destroyed(void) {} // Called after the entity has been destroyed + /** Applies friction to an entity + @param a_Speed The speed vector to apply changes to + @param a_SlowdownMultiplier The factor to reduce the speed by + */ + static void ApplyFriction(Vector3d & a_Speed, double a_SlowdownMultiplier, float a_Dt); + /** Called in each tick to handle air-related processing i.e. drowning */ virtual void HandleAir(void); -- cgit v1.2.3 From fdabfd77e22397e149740bb5cb09a2f77805f05f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 13 Sep 2014 22:49:27 +0100 Subject: Improved cBlockHandler::DropBlock --- src/Blocks/BlockBigFlower.h | 6 ++-- src/Blocks/BlockHandler.cpp | 68 +++++++++++++++++++-------------------------- src/Blocks/BlockHandler.h | 2 +- src/Items/ItemHandler.cpp | 2 +- src/Mobs/Monster.cpp | 2 +- 5 files changed, 34 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 646980634..89ffc864d 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -19,16 +19,16 @@ public: } - virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop, bool a_DropVerbatim) override + virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); if (Meta & 0x8) { - super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ, a_CanDrop, a_DropVerbatim); + super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ, a_CanDrop); } else { - super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_CanDrop, a_DropVerbatim); + super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_CanDrop); } } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 8a8bdd3c8..cee2f4b99 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -419,57 +419,45 @@ void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) -void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop, bool a_DropVerbatim) +void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop) { cItems Pickups; NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); if (a_CanDrop) { - if (!a_DropVerbatim) - { - ConvertToPickups(Pickups, Meta); - } - else - { - // TODO: Add a proper overridable function for this - if (a_Digger != NULL) + if ((a_Digger != NULL) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)) + { + switch (m_BlockType) { - cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; - if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: { - switch (m_BlockType) - { - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_CROPS: - { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - break; - }; - default: Pickups.Add(m_BlockType, 1, Meta); - } - } - else - { - Pickups.Add(m_BlockType, 1, Meta); + // Silktouch can't be used for these blocks + ConvertToPickups(Pickups, Meta); + break; } + default: Pickups.Add(m_BlockType, 1, Meta); break; } } + else + { + ConvertToPickups(Pickups, Meta); + } } // Allow plugins to modify the pickups: diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index b3ada279c..3a8115da0 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -82,7 +82,7 @@ public: @param a_CanDrop Informs the handler whether the block should be dropped at all. One example when this is false is when stone is destroyed by hand @param a_DropVerbatim Calls ConvertToVerbatimPickups() instead of its counterpart, meaning the block itself is dropped by default (due to a speical tool or enchantment) */ - virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop = true, bool a_DropVerbatim = false); + virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop = true); /// Checks if the block can stay at the specified relative coords in the chunk virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index f7882a50f..8c3f28c74 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -334,7 +334,7 @@ void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const { cChunkInterface ChunkInterface(a_World->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*a_World); - Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, CanHarvestBlock(Block), a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, a_Player, a_BlockX, a_BlockY, a_BlockZ, CanHarvestBlock(Block)); } if (!cBlockInfo::IsOneHitDig(Block)) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 7e40794b1..81acf1a93 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -283,7 +283,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) } } - Vector3f Distance = m_Destination - GetPosition(); + Vector3d Distance = m_Destination - GetPosition(); if (!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move { Distance.y = 0; -- cgit v1.2.3 From c4a53c5d7dadc8303eeac2d92a7513c63c2f776e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Sep 2014 01:28:09 +0200 Subject: OSSupport: Fixed UNICODE Windows builds. The files now compile even inside UNICODE applications. --- src/OSSupport/File.cpp | 14 +++++++------- src/OSSupport/IsThread.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 2194c46ee..cb6031da6 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -298,7 +298,7 @@ bool cFile::Rename(const AString & a_OrigFileName, const AString & a_NewFileName bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName) { #ifdef _WIN32 - return (CopyFile(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0); + return (CopyFileA(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0); #else // Other OSs don't have a direct CopyFile equivalent, do it the harder way: std::ifstream src(a_SrcFileName.c_str(), std::ios::binary); @@ -322,7 +322,7 @@ bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName) bool cFile::IsFolder(const AString & a_Path) { #ifdef _WIN32 - DWORD FileAttrib = GetFileAttributes(a_Path.c_str()); + DWORD FileAttrib = GetFileAttributesA(a_Path.c_str()); return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0)); #else struct stat st; @@ -337,7 +337,7 @@ bool cFile::IsFolder(const AString & a_Path) bool cFile::IsFile(const AString & a_Path) { #ifdef _WIN32 - DWORD FileAttrib = GetFileAttributes(a_Path.c_str()); + DWORD FileAttrib = GetFileAttributesA(a_Path.c_str()); return ((FileAttrib != INVALID_FILE_ATTRIBUTES) && ((FileAttrib & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0)); #else struct stat st; @@ -366,7 +366,7 @@ int cFile::GetSize(const AString & a_FileName) bool cFile::CreateFolder(const AString & a_FolderPath) { #ifdef _WIN32 - return (CreateDirectory(a_FolderPath.c_str(), NULL) != 0); + return (CreateDirectoryA(a_FolderPath.c_str(), NULL) != 0); #else return (mkdir(a_FolderPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0); #endif @@ -396,13 +396,13 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) // Find all files / folders: FileFilter.append("*.*"); HANDLE hFind; - WIN32_FIND_DATA FindFileData; - if ((hFind = FindFirstFile(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) + WIN32_FIND_DATAA FindFileData; + if ((hFind = FindFirstFileA(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) { do { AllFiles.push_back(FindFileData.cFileName); - } while (FindNextFile(hFind, &FindFileData)); + } while (FindNextFileA(hFind, &FindFileData)); FindClose(hFind); } diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index c20fc3e7e..5de5f31c4 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -69,7 +69,7 @@ protected: static DWORD __stdcall thrExecute(LPVOID a_Param) { // Create a window so that the thread can be identified by 3rd party tools: - HWND IdentificationWnd = CreateWindow("STATIC", ((cIsThread *)a_Param)->m_ThreadName.c_str(), 0, 0, 0, 0, WS_OVERLAPPED, NULL, NULL, NULL, NULL); + HWND IdentificationWnd = CreateWindowA("STATIC", ((cIsThread *)a_Param)->m_ThreadName.c_str(), 0, 0, 0, 0, WS_OVERLAPPED, NULL, NULL, NULL, NULL); // Run the thread: ((cIsThread *)a_Param)->Execute(); -- cgit v1.2.3 From 382a42b3d6a5b1808ad9c8bfe1494ad44676c14b Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 14 Sep 2014 14:24:28 +0200 Subject: Fixed warnings. --- src/Protocol/ChunkDataSerializer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 268cf4a9f..61df24c31 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -192,8 +192,8 @@ void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_Chu { BLOCKTYPE BlockType = m_BlockTypes[Index] & 0xFF; NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; - Blocks[LastOffset] = (BlockType << 4) | ((unsigned char)BlockMeta); - Blocks[LastOffset + 1] = (unsigned char)BlockType >> 4; + Blocks[LastOffset] = (unsigned char)(BlockType << 4) | BlockMeta; + Blocks[LastOffset + 1] = (unsigned char)(BlockType >> 4); LastOffset += 2; } @@ -215,7 +215,7 @@ void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_Chu Packet.WriteBEInt(a_ChunkX); Packet.WriteBEInt(a_ChunkZ); Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag - Packet.WriteBEShort(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff + Packet.WriteBEShort((short) 0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff Packet.WriteVarInt(DataSize); // Chunk size Packet.WriteBuf(AllData, DataSize); // Chunk data -- cgit v1.2.3 From 63142a7eb151ef8ae3842406366f65ec67d3d0d2 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 14 Sep 2014 20:08:18 +0200 Subject: Simplified WriteUUID() --- src/Protocol/Protocol18x.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 54dea049b..837c8ec99 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1573,6 +1573,7 @@ int cProtocol180::GetParticleID(const AString & a_ParticleName) if (ParticleMap.find(ParticleName) == ParticleMap.end()) { LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); + ASSERT(!"Unknown particle"); return 0; } @@ -2672,20 +2673,19 @@ cProtocol180::cPacketizer::~cPacketizer() void cProtocol180::cPacketizer::WriteUUID(const AString & a_UUID) { - AString UUID_1 = a_UUID.substr(0, a_UUID.length() / 2); - AString UUID_2 = a_UUID.substr(a_UUID.length() / 2); + if (a_UUID.length() != 32) + { + LOGWARNING("Attempt to send a bad uuid (length isn't 32): %s", a_UUID.c_str()); + ASSERT(!"Wrong uuid length!"); + return; + } + AString UUID_1 = a_UUID.substr(0, 16); + AString UUID_2 = a_UUID.substr(16); Int64 Value_1, Value_2; sscanf(UUID_1.c_str(), "%llx", &Value_1); sscanf(UUID_2.c_str(), "%llx", &Value_2); - AString SValue_1, SValue_2; - Printf(SValue_1, "%lld", Value_1); - Printf(SValue_2, "%lld", Value_2); - - StringToInteger(SValue_1.c_str(), Value_1); - StringToInteger(SValue_2.c_str(), Value_2); - WriteInt64(Value_1); WriteInt64(Value_2); } -- cgit v1.2.3 From 96f45a48d4eb757096bc325f45729a21fba72caf Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 15 Sep 2014 22:34:33 +0200 Subject: VoronoiMap: Added Jitter and OddRowOffset params. --- src/VoronoiMap.cpp | 35 ++++++++++++++++++++++++++++++----- src/VoronoiMap.h | 31 +++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp index 5efd09c01..68147ebfc 100644 --- a/src/VoronoiMap.cpp +++ b/src/VoronoiMap.cpp @@ -10,11 +10,13 @@ -cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) : +cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize, int a_JitterSize) : m_Noise1(a_Seed + 1), m_Noise2(a_Seed + 2), m_Noise3(a_Seed + 3), - m_CellSize(a_CellSize), + m_CellSize(std::max(a_CellSize, 2)), + m_JitterSize(Clamp(a_JitterSize, 1, a_CellSize)), + m_OddRowOffset(0), m_CurrentCellX(9999999), // Cell coords that are definitely out of the range for normal generator, so that the first query will overwrite them m_CurrentCellZ(9999999) { @@ -26,7 +28,29 @@ cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) : void cVoronoiMap::SetCellSize(int a_CellSize) { + a_CellSize = std::max(a_CellSize, 2); // Cell size must be at least 2 m_CellSize = a_CellSize; + + // For compatibility with previous version, which didn't have the jitter, we set jitter here as well. + m_JitterSize = a_CellSize; +} + + + + + +void cVoronoiMap::SetJitterSize(int a_JitterSize) +{ + m_JitterSize = Clamp(a_JitterSize, 1, m_CellSize); +} + + + + + +void cVoronoiMap::SetOddRowOffset(int a_OddRowOffset) +{ + m_OddRowOffset = Clamp(a_OddRowOffset, -m_CellSize, m_CellSize); } @@ -111,12 +135,13 @@ void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ) for (int x = 0; x < 5; x++) { int BaseX = (NoiseBaseX + x) * m_CellSize; + int OddRowOffset = ((NoiseBaseX + x) & 0x01) * m_OddRowOffset; for (int z = 0; z < 5; z++) { - int OffsetX = (m_Noise1.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize; - int OffsetZ = (m_Noise2.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize; + int OffsetX = (m_Noise1.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_JitterSize; + int OffsetZ = (m_Noise2.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_JitterSize; m_SeedX[x][z] = BaseX + OffsetX; - m_SeedZ[x][z] = (NoiseBaseZ + z) * m_CellSize + OffsetZ; + m_SeedZ[x][z] = (NoiseBaseZ + z) * m_CellSize + OddRowOffset + OffsetZ; } // for z } // for x m_CurrentCellX = a_CellX; diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h index 84cf206e9..49f6c1da1 100644 --- a/src/VoronoiMap.h +++ b/src/VoronoiMap.h @@ -18,18 +18,28 @@ class cVoronoiMap { public: - cVoronoiMap(int a_Seed, int a_CellSize = 128); + cVoronoiMap(int a_Seed, int a_CellSize = 128, int a_JitterSize = 128); - /// Sets the cell size used for generating the Voronoi seeds + /** Sets both the cell size and jitter size used for generating the Voronoi seeds. */ void SetCellSize(int a_CellSize); + + /** Sets the jitter size. Clamps it to current cell size. */ + void SetJitterSize(int a_JitterSize); + + /** Sets the offset that is added to each odd row of cells. + This offset makes the voronoi cells align to a non-grid. + Clamps the value to [-m_CellSize, +m_CellSize]. */ + void SetOddRowOffset(int a_OddRowOffset); - /// Returns the value in the cell into which the specified point lies + /** Returns the value in the cell into which the specified point lies. */ int GetValueAt(int a_X, int a_Y); - /// Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed + /** Returns the value in the cell into which the specified point lies, + and the distance to the nearest Voronoi seed. */ int GetValueAt(int a_X, int a_Y, int & a_MinDistance); - /// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache + /** Returns the value in the cell into which the specified point lies, + and the distances to the 2 nearest Voronoi seeds. Uses a cache. */ int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2); protected: @@ -38,8 +48,17 @@ protected: cNoise m_Noise2; cNoise m_Noise3; - /// Size of the Voronoi cells (avg X/Y distance between the seeds) + /** Size of the Voronoi cells (avg X/Y distance between the seeds). Expected to be at least 2. */ int m_CellSize; + + /** The amount that the cell seeds may be offset from the grid. + Expected to be at least 1 and less than m_CellSize. */ + int m_JitterSize; + + /** The constant amount that the cell seeds of every odd row will be offset from the grid. + This allows us to have non-rectangular grids. + Expected to be between -m_CellSize and +m_CellSize. */ + int m_OddRowOffset; /** The X coordinate of the currently cached cell neighborhood */ int m_CurrentCellX; -- cgit v1.2.3 From be7483f26be138e337344b61799396994d3858a3 Mon Sep 17 00:00:00 2001 From: nesco Date: Tue, 16 Sep 2014 20:01:04 +0200 Subject: Pre 1.8 release Added Gamemode Spectator --- src/Defines.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/Defines.h b/src/Defines.h index 78c58034e..6355b75b4 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -115,12 +115,14 @@ enum eGameMode eGameMode_Survival = 0, eGameMode_Creative = 1, eGameMode_Adventure = 2, + eGameMode_Spectator = 3, // Easier-to-use synonyms: gmNotSet = eGameMode_NotSet, gmSurvival = eGameMode_Survival, gmCreative = eGameMode_Creative, gmAdventure = eGameMode_Adventure, + gmSpectator = eGameMode_Spectator, // These two are used to check GameMode for validity when converting from integers. gmMax, // Gets automatically assigned -- cgit v1.2.3 From 8dedbe4db52ee434595d9bdb32b3850a6c1e175f Mon Sep 17 00:00:00 2001 From: nesco Date: Tue, 16 Sep 2014 20:02:27 +0200 Subject: Preparing 1.8 changes Added Spectator Gamemode --- src/Entities/Player.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 9821cc6d9..d64dd6b99 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -171,6 +171,9 @@ public: /** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */ bool IsGameModeAdventure(void) const; + /** Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current world */ + bool IsGameModeSpectator(void) const; + AString GetIP(void) const { return m_IP; } // tolua_export /** Returns the associated team, NULL if none */ -- cgit v1.2.3 From 120b23d65eefdd6e29b1605b10b852a1069e5444 Mon Sep 17 00:00:00 2001 From: nesco Date: Tue, 16 Sep 2014 20:04:17 +0200 Subject: Pre 1.8 release Added Spectator gamemode --- src/Entities/Player.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ea795e346..81250bd40 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1043,6 +1043,14 @@ bool cPlayer::IsGameModeAdventure(void) const +bool cPlayer::IsGameModeSpectator(void) const +{ + return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator + ((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Adventure +} + + + void cPlayer::SetTeam(cTeam * a_Team) { -- cgit v1.2.3 From f246faec1636ba9a7e5850dfbbb568d1b7dff0b9 Mon Sep 17 00:00:00 2001 From: nesco Date: Tue, 16 Sep 2014 20:05:55 +0200 Subject: Preparing 1.8 update Added Spectator gamemode --- src/World.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/World.h b/src/World.h index 0c57e6611..6f680694f 100644 --- a/src/World.h +++ b/src/World.h @@ -188,6 +188,9 @@ public: /** Returns true if the world is in Adventure mode */ bool IsGameModeAdventure(void) const { return (m_GameMode == gmAdventure); } + /** Returns true if the world is in Spectator mode */ + bool IsGameModeAdventure(void) const { return (m_GameMode == gmSpectator); } + bool IsPVPEnabled(void) const { return m_bEnabledPVP; } bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; } -- cgit v1.2.3 From 89c9aec5da5adfcaee06df9979bc701579d19f6d Mon Sep 17 00:00:00 2001 From: nesco Date: Tue, 16 Sep 2014 20:17:35 +0200 Subject: Preparing 1.8 update Partially added Spectator gamemode --- src/Entities/Player.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 81250bd40..0f15ba620 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1166,7 +1166,7 @@ void cPlayer::SetGameMode(eGameMode a_GameMode) m_GameMode = a_GameMode; m_ClientHandle->SendGameMode(a_GameMode); - if (!IsGameModeCreative()) + if (!(IsGameModeCreative() || IsGameModeSpectator())) { SetFlying(false); SetCanFly(false); @@ -1348,6 +1348,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos) void cPlayer::SetVisible(bool a_bVisible) { + // Need to Check if this or other players are in gamemode spectator if (a_bVisible && !m_bVisible) // Make visible { m_bVisible = true; -- cgit v1.2.3 From 26a4845a995065f0ed24ef0e21e4c9bf44cef002 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 16 Sep 2014 20:29:31 +0100 Subject: IncrementalRedstoneSimulator now has no dependencies on cChunk --- src/Chunk.h | 11 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 11 +- src/Simulator/IncrementalRedstoneSimulator.h | 312 +----------------- src/Simulator/IncrementalRedstoneSimulator.inc | 417 ++++++++++++++++++++++--- src/Simulator/RedstoneSimulator.h | 6 + src/World.cpp | 2 +- 6 files changed, 384 insertions(+), 375 deletions(-) (limited to 'src') diff --git a/src/Chunk.h b/src/Chunk.h index 9a0e96513..4e8404595 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -417,11 +417,6 @@ public: cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; } cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; } - cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; } - cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; } - cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; } - cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; } - cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; } bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; } void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; } @@ -507,11 +502,7 @@ private: cSandSimulatorChunkData m_SandSimulatorData; cRedstoneSimulatorChunkData m_RedstoneSimulatorData; - cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData; - cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList; - cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList; - cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList; - cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList; + /** Indicates if simulate-once blocks should be updated by the redstone simulator */ bool m_IsRedstoneDirty; diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 515d72457..55cc014f3 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1,9 +1,6 @@ #include "Globals.h" -#ifndef SELF_TEST - -#include "IncrementalRedstoneSimulator.h" #include "IncrementalRedstoneSimulator.inc" @@ -18,6 +15,8 @@ #include "Blocks/BlockPiston.h" #include "BlockEntities/ChestEntity.h" -#pragma clang diagnostic ignored "-Wweak-template-vtables" -template class cIncrementalRedstoneSimulator; -#endif +cRedstoneSimulator * MakeIncrementalRedstoneSimulator(cWorld & a_World) +{ + return new cIncrementalRedstoneSimulator(a_World); +} + diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 0120a3208..5bd1ad95d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -3,313 +3,7 @@ #include "RedstoneSimulator.h" -/// Per-chunk data for the simulator, specified individual chunks to simulate -typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData; - -class cRedstonePoweredEntity; - -typedef cItemCallback cRedstonePoweredCallback; - - -template class GetHandlerCompileTime, class ChestType> -class cIncrementalRedstoneSimulator : - public cRedstoneSimulator -{ - typedef cRedstoneSimulator super; -public: - - cIncrementalRedstoneSimulator(WorldType & a_World); - ~cIncrementalRedstoneSimulator(); - - virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override; - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); } - virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override; - - enum eRedstoneDirection - { - REDSTONE_NONE = 0, - REDSTONE_X_POS = 0x1, - REDSTONE_X_NEG = 0x2, - REDSTONE_Z_POS = 0x4, - REDSTONE_Z_NEG = 0x8, - }; - eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ); - -private: - - #define MAX_POWER_LEVEL 15 - - struct sPoweredBlocks // Define structure of the directly powered blocks list - { - Vector3i a_BlockPos; // Position of powered block - Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos - unsigned char a_PowerLevel; - }; - - struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side) - { - Vector3i a_BlockPos; - Vector3i a_MiddlePos; // Position of block that is betwixt a source and the destination - Vector3i a_SourcePos; - unsigned char a_PowerLevel; - }; - - struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player) - { - Vector3i a_RelBlockPos; - bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate - }; - - struct sRepeatersDelayList // Define structure of list containing repeaters' delay states - { - Vector3i a_RelBlockPos; - unsigned char a_DelayTicks; // For how many ticks should the repeater delay - unsigned char a_ElapsedTicks; // How much of the previous has been elapsed? - bool ShouldPowerOn; // What happens when the delay time is fulfilled? - }; - -public: - - typedef std::vector PoweredBlocksList; - typedef std::vector LinkedBlocksList; - typedef std::vector SimulatedPlayerToggleableList; - typedef std::vector RepeatersDelayList; - -private: - - cRedstoneSimulatorChunkData * m_RedstoneSimulatorChunkData; - PoweredBlocksList * m_PoweredBlocks; - LinkedBlocksList * m_LinkedPoweredBlocks; - SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks; - RepeatersDelayList * m_RepeatersDelayList; - - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); } - void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL); - ChunkType * m_Chunk; - - // We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly - // In addition to being non-performant, it would stop the player from actually breaking said device - - /* ====== SOURCES ====== */ - /** Handles the redstone torch */ - void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); - /** Handles the redstone block */ - void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles levers */ - void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles buttons */ - void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles daylight sensors */ - void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles pressure plates */ - void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); - /** Handles tripwire hooks - Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook - If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task - */ - void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles trapped chests */ - void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /* ==================== */ - - /* ====== CARRIERS ====== */ - /** Handles redstone wire */ - void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles repeaters */ - void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); - /* ====================== */ - - /* ====== DEVICES ====== */ - /** Handles pistons */ - void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles dispensers and droppers */ - void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles TNT (exploding) */ - void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles redstone lamps */ - void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); - /** Handles doords */ - void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles command blocks */ - void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles activator, detector, and powered rails */ - void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); - /** Handles trapdoors */ - void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles fence gates */ - void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles noteblocks */ - void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Handles tripwires */ - void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /* ===================== */ - - /* ====== Helper functions ====== */ - /** Marks a block as powered */ - void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL); - /** Marks a block as being powered through another block */ - void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL); - /** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */ - void SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered); - /** Marks the second block in a direction as linked powered */ - void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL); - /** Marks all blocks immediately surrounding a coordinate as powered */ - void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL); - /** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */ - bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn); - /** Removes a block from the Powered and LinkedPowered lists - Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests - */ - void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, ChunkType * a_Chunk, bool a_IsFirstCall = true); - - /** Returns if a coordinate is powered or linked powered */ - bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); } - /** Returns if a coordinate is in the directly powered blocks list */ - bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk); - /** Returns if a coordinate is in the indirectly powered blocks list */ - bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); - /** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */ - bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered); - /** Returns if a repeater is powered by testing for power sources behind the repeater */ - bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); - /** Returns if a repeater is locked */ - bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); - /** Returns if a piston is powered */ - bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); - /** Returns if a wire is powered - The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */ - bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel); - /** Handles delayed updates to repeaters **/ - void HandleRedstoneRepeaterDelays(void); - - /** Returns if lever metadata marks it as emitting power */ - bool IsLeverOn(NIBBLETYPE a_BlockMeta); - /** Returns if button metadata marks it as emitting power */ - bool IsButtonOn(NIBBLETYPE a_BlockMeta) { return IsLeverOn(a_BlockMeta); } - /* ============================== */ - - /* ====== Misc Functions ====== */ - /** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */ - inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); } - - /** Returns if a block is a mechanism (something that accepts power and does something) - Used by torches to determine if they power a block whilst not standing on the ground - */ - inline static bool IsMechanism(BLOCKTYPE Block) - { - switch (Block) - { - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_COMMAND_BLOCK: - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_HOPPER: - case E_BLOCK_NOTE_BLOCK: - case E_BLOCK_TNT: - case E_BLOCK_TRAPDOOR: - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_POWERED_RAIL: - case E_BLOCK_REDSTONE_WIRE: - { - return true; - } - default: return false; - } - } - - /** Returns if a block has the potential to output power */ - inline static bool IsPotentialSource(BLOCKTYPE Block) - { - switch (Block) - { - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_DAYLIGHT_SENSOR: - case E_BLOCK_WOODEN_BUTTON: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_LEVER: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_TRAPPED_CHEST: - { - return true; - } - default: return false; - } - } - - /** Returns if a block is any sort of redstone device */ - inline static bool IsRedstone(BLOCKTYPE Block) - { - switch (Block) - { - // All redstone devices, please alpha sort - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_COMMAND_BLOCK: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_DISPENSER: - case E_BLOCK_DAYLIGHT_SENSOR: - case E_BLOCK_DROPPER: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_HOPPER: - case E_BLOCK_INACTIVE_COMPARATOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_LEVER: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_NOTE_BLOCK: - case E_BLOCK_POWERED_RAIL: - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_STICKY_PISTON: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_TNT: - case E_BLOCK_TRAPDOOR: - case E_BLOCK_TRAPPED_CHEST: - case E_BLOCK_TRIPWIRE_HOOK: - case E_BLOCK_TRIPWIRE: - case E_BLOCK_WOODEN_BUTTON: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_PISTON: - { - return true; - } - default: return false; - } - } - - inline static bool AreCoordsOnChunkBoundary(int a_BlockX, int a_BlockY, int a_BlockZ) - { - return ( // Are we on a chunk boundary? +- 2 because of LinkedPowered blocks - ((a_BlockX % cChunkDef::Width) <= 1) || - ((a_BlockX % cChunkDef::Width) >= 14) || - ((a_BlockZ % cChunkDef::Width) <= 1) || - ((a_BlockZ % cChunkDef::Width) >= 14) - ); - } -}; +class cWorld; +class cChunk; +cRedstoneSimulator * MakeIncrementalRedstoneSimulator(cWorld & a_World); diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index 6d1f7b0ae..e3c856328 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -3,20 +3,334 @@ #include "BoundingBox.h" #include "BlockEntities/RedstonePoweredEntity.h" #include "Blocks/ChunkInterface.h" +#include "RedstoneSimulator.h" + + + +typedef cItemCallback cRedstonePoweredCallback; + + template class GetHandlerCompileTime, class ChestType> -cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(WorldType & a_World) : - super(a_World), - m_RedstoneSimulatorChunkData(), - m_PoweredBlocks(), - m_LinkedPoweredBlocks(), - m_SimulatedPlayerToggleableBlocks(), - m_RepeatersDelayList(), - m_Chunk() +class cIncrementalRedstoneSimulator : + public cRedstoneSimulator { -} + typedef cRedstoneSimulator super; +public: + + cIncrementalRedstoneSimulator(WorldType & a_World) + : cRedstoneSimulator(a_World) + { + } + ~cIncrementalRedstoneSimulator(); + + virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used + virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override; + virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override { return IsRedstone(a_BlockType); } + virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override; + + enum eRedstoneDirection + { + REDSTONE_NONE = 0, + REDSTONE_X_POS = 0x1, + REDSTONE_X_NEG = 0x2, + REDSTONE_Z_POS = 0x4, + REDSTONE_Z_NEG = 0x8, + }; + eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ); + +private: + + #define MAX_POWER_LEVEL 15 + + struct sPoweredBlocks // Define structure of the directly powered blocks list + { + Vector3i a_BlockPos; // Position of powered block + Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos + unsigned char a_PowerLevel; + }; + + struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side) + { + Vector3i a_BlockPos; + Vector3i a_MiddlePos; // Position of block that is betwixt a source and the destination + Vector3i a_SourcePos; + unsigned char a_PowerLevel; + }; + + struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player) + { + Vector3i a_RelBlockPos; + bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate + }; + + struct sRepeatersDelayList // Define structure of list containing repeaters' delay states + { + Vector3i a_RelBlockPos; + unsigned char a_DelayTicks; // For how many ticks should the repeater delay + unsigned char a_ElapsedTicks; // How much of the previous has been elapsed? + bool ShouldPowerOn; // What happens when the delay time is fulfilled? + }; + + class cIncrementalRedstoneSimulatorChunkData : + cRedstoneSimulatorChunkData + { + public: + /// Per-chunk data for the simulator, specified individual chunks to simulate + cCoordWithBlockAndBoolVector m_ChunkData; + cCoordWithBlockAndBoolVector m_QueuedChunkData; + std::vector m_PoweredBlocks; + std::vector m_LinkedBlocks; + std::vector m_SimulatedPlayerToggleableBlocks; + std::vector m_RepeatersDelayList; + }; + +public: + + typedef std::vector PoweredBlocksList; + typedef std::vector LinkedBlocksList; + typedef std::vector SimulatedPlayerToggleableList; + typedef std::vector RepeatersDelayList; + +private: + + cIncrementalRedstoneSimulatorChunkData * m_RedstoneSimulatorChunkData; + PoweredBlocksList * m_PoweredBlocks; + LinkedBlocksList * m_LinkedPoweredBlocks; + SimulatedPlayerToggleableList * m_SimulatedPlayerToggleableBlocks; + RepeatersDelayList * m_RepeatersDelayList; + + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk) override { RedstoneAddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); } + void RedstoneAddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, ChunkType * a_Chunk, ChunkType * a_OtherChunk = NULL); + ChunkType * m_Chunk; + + // We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly + // In addition to being non-performant, it would stop the player from actually breaking said device + + /* ====== SOURCES ====== */ + /** Handles the redstone torch */ + void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); + /** Handles the redstone block */ + void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles levers */ + void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles buttons */ + void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles daylight sensors */ + void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles pressure plates */ + void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); + /** Handles tripwire hooks + Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook + If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task + */ + void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles trapped chests */ + void HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /* ==================== */ + + /* ====== CARRIERS ====== */ + /** Handles redstone wire */ + void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles repeaters */ + void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); + /* ====================== */ + + /* ====== DEVICES ====== */ + /** Handles pistons */ + void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles dispensers and droppers */ + void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles TNT (exploding) */ + void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles redstone lamps */ + void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState); + /** Handles doords */ + void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles command blocks */ + void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles activator, detector, and powered rails */ + void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); + /** Handles trapdoors */ + void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles fence gates */ + void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles noteblocks */ + void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles tripwires */ + void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /* ===================== */ + + /* ====== Helper functions ====== */ + /** Marks a block as powered */ + void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL); + /** Marks a block as being powered through another block */ + void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL); + /** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */ + void SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered); + /** Marks the second block in a direction as linked powered */ + void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL); + /** Marks all blocks immediately surrounding a coordinate as powered */ + void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL); + /** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */ + bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn); + /** Removes a block from the Powered and LinkedPowered lists + Used for variable sources such as tripwire hooks, daylight sensors, and trapped chests + */ + void SetSourceUnpowered(int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, ChunkType * a_Chunk, bool a_IsFirstCall = true); + + /** Returns if a coordinate is powered or linked powered */ + bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); } + /** Returns if a coordinate is in the directly powered blocks list */ + bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, ChunkType * a_Chunk); + /** Returns if a coordinate is in the indirectly powered blocks list */ + bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */ + bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered); + /** Returns if a repeater is powered by testing for power sources behind the repeater */ + bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); + /** Returns if a repeater is locked */ + bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); + /** Returns if a piston is powered */ + bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta); + /** Returns if a wire is powered + The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */ + bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel); + /** Handles delayed updates to repeaters **/ + void HandleRedstoneRepeaterDelays(void); + + /** Returns if lever metadata marks it as emitting power */ + bool IsLeverOn(NIBBLETYPE a_BlockMeta); + /** Returns if button metadata marks it as emitting power */ + bool IsButtonOn(NIBBLETYPE a_BlockMeta) { return IsLeverOn(a_BlockMeta); } + /* ============================== */ + + /* ====== Misc Functions ====== */ + /** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */ + inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); } + + /** Returns if a block is a mechanism (something that accepts power and does something) + Used by torches to determine if they power a block whilst not standing on the ground + */ + inline static bool IsMechanism(BLOCKTYPE Block) + { + switch (Block) + { + case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + case E_BLOCK_DISPENSER: + case E_BLOCK_DROPPER: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_HOPPER: + case E_BLOCK_NOTE_BLOCK: + case E_BLOCK_TNT: + case E_BLOCK_TRAPDOOR: + case E_BLOCK_REDSTONE_LAMP_OFF: + case E_BLOCK_REDSTONE_LAMP_ON: + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_REDSTONE_WIRE: + { + return true; + } + default: return false; + } + } + + /** Returns if a block has the potential to output power */ + inline static bool IsPotentialSource(BLOCKTYPE Block) + { + switch (Block) + { + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_DAYLIGHT_SENSOR: + case E_BLOCK_WOODEN_BUTTON: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_LEVER: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_TRAPPED_CHEST: + { + return true; + } + default: return false; + } + } + + /** Returns if a block is any sort of redstone device */ + inline static bool IsRedstone(BLOCKTYPE Block) + { + switch (Block) + { + // All redstone devices, please alpha sort + case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_DISPENSER: + case E_BLOCK_DAYLIGHT_SENSOR: + case E_BLOCK_DROPPER: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_HOPPER: + case E_BLOCK_INACTIVE_COMPARATOR: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_LEVER: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_NOTE_BLOCK: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_REDSTONE_LAMP_OFF: + case E_BLOCK_REDSTONE_LAMP_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_STICKY_PISTON: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_TNT: + case E_BLOCK_TRAPDOOR: + case E_BLOCK_TRAPPED_CHEST: + case E_BLOCK_TRIPWIRE_HOOK: + case E_BLOCK_TRIPWIRE: + case E_BLOCK_WOODEN_BUTTON: + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_PISTON: + { + return true; + } + default: return false; + } + } + + inline static bool AreCoordsOnChunkBoundary(int a_BlockX, int a_BlockY, int a_BlockZ) + { + return ( // Are we on a chunk boundary? +- 2 because of LinkedPowered blocks + ((a_BlockX % cChunkDef::Width) <= 1) || + ((a_BlockX % cChunkDef::Width) >= 14) || + ((a_BlockZ % cChunkDef::Width) <= 1) || + ((a_BlockZ % cChunkDef::Width) >= 14) + ); + } +}; + @@ -70,8 +384,8 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorPoweredBlocksList(); - for (typename PoweredBlocksList::iterator itr = PoweredBlocks->begin(); itr != PoweredBlocks->end();) + PoweredBlocksList & PoweredBlocks = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks; + for (typename PoweredBlocksList::iterator itr = PoweredBlocks.begin(); itr != PoweredBlocks.end();) { if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { @@ -82,7 +396,7 @@ void cIncrementalRedstoneSimulatora_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = PoweredBlocks->erase(itr); + itr = PoweredBlocks.erase(itr); continue; } else if ( @@ -95,22 +409,22 @@ void cIncrementalRedstoneSimulatora_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = PoweredBlocks->erase(itr); + itr = PoweredBlocks.erase(itr); continue; } ++itr; } - LinkedBlocksList * LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); + LinkedBlocksList & LinkedPoweredBlocks = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks; // We loop through all values (insteading of breaking out at the first) to make sure everything is gone, as there can be multiple SourceBlock entries for one AddBlock coordinate - for (typename LinkedBlocksList::iterator itr = LinkedPoweredBlocks->begin(); itr != LinkedPoweredBlocks->end();) + for (typename LinkedBlocksList::iterator itr = LinkedPoweredBlocks.begin(); itr != LinkedPoweredBlocks.end();) { if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { if (!IsPotentialSource(Block)) { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); + itr = LinkedPoweredBlocks.erase(itr); continue; } else if ( @@ -121,7 +435,7 @@ void cIncrementalRedstoneSimulatora_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); + itr = LinkedPoweredBlocks.erase(itr); continue; } } @@ -130,15 +444,15 @@ void cIncrementalRedstoneSimulatora_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); - itr = LinkedPoweredBlocks->erase(itr); + itr = LinkedPoweredBlocks.erase(itr); continue; } } ++itr; } - SimulatedPlayerToggleableList * SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); - for (typename SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks->begin(); itr != SimulatedPlayerToggleableBlocks->end(); ++itr) + SimulatedPlayerToggleableList & SimulatedPlayerToggleableBlocks = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_SimulatedPlayerToggleableBlocks; + for (typename SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks.begin(); itr != SimulatedPlayerToggleableBlocks.end(); ++itr) { if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) { @@ -148,13 +462,13 @@ void cIncrementalRedstoneSimulatora_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z); - SimulatedPlayerToggleableBlocks->erase(itr); + SimulatedPlayerToggleableBlocks.erase(itr); break; } } - RepeatersDelayList * RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); - for (typename RepeatersDelayList::iterator itr = RepeatersDelayList->begin(); itr != RepeatersDelayList->end(); ++itr) + RepeatersDelayList & RepeatersDelayList = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_RepeatersDelayList; + for (typename RepeatersDelayList::iterator itr = RepeatersDelayList.begin(); itr != RepeatersDelayList.end(); ++itr) { if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ))) { @@ -163,7 +477,7 @@ void cIncrementalRedstoneSimulatorerase(itr); + RepeatersDelayList.erase(itr); break; } } @@ -174,8 +488,8 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorData(); - for (cRedstoneSimulatorChunkData::iterator itr = RedstoneSimulatorChunkData->begin(); itr != RedstoneSimulatorChunkData->end(); ++itr) + cCoordWithBlockAndBoolVector & RedstoneSimulatorChunkData = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_ChunkData; + for (cCoordWithBlockAndBoolVector::iterator itr = RedstoneSimulatorChunkData.begin(); itr != RedstoneSimulatorChunkData.end(); ++itr) { if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block { @@ -197,7 +511,8 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorQueuedData()->begin(); itr != a_Chunk->GetRedstoneSimulatorQueuedData()->end(); ++itr) + cCoordWithBlockAndBoolVector & QueuedData = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData; + for (cCoordWithBlockAndBoolVector::iterator itr = QueuedData.begin(); itr != QueuedData.end(); ++itr) { if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) { @@ -205,7 +520,7 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorQueuedData()->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false)); + QueuedData.push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false)); } @@ -214,19 +529,23 @@ void cIncrementalRedstoneSimulator class GetHandlerCompileTime, class ChestType> void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) { - m_RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData(); - if (m_RedstoneSimulatorChunkData->empty() && a_Chunk->GetRedstoneSimulatorQueuedData()->empty()) + m_RedstoneSimulatorChunkData = (cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData(); + if (m_RedstoneSimulatorChunkData->m_ChunkData.empty() && ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData.empty()) { return; } - m_RedstoneSimulatorChunkData->insert(m_RedstoneSimulatorChunkData->end(), a_Chunk->GetRedstoneSimulatorQueuedData()->begin(), a_Chunk->GetRedstoneSimulatorQueuedData()->end()); - a_Chunk->GetRedstoneSimulatorQueuedData()->clear(); + m_RedstoneSimulatorChunkData->m_ChunkData.insert( + m_RedstoneSimulatorChunkData->m_ChunkData.end(), + m_RedstoneSimulatorChunkData ->m_QueuedChunkData.begin(), + m_RedstoneSimulatorChunkData ->m_QueuedChunkData.end()); + + m_RedstoneSimulatorChunkData->m_QueuedChunkData.clear(); - m_PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList(); - m_RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList(); - m_SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList(); - m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList(); + m_PoweredBlocks = &m_RedstoneSimulatorChunkData->m_PoweredBlocks; + m_RepeatersDelayList = &m_RedstoneSimulatorChunkData->m_RepeatersDelayList; + m_SimulatedPlayerToggleableBlocks = &m_RedstoneSimulatorChunkData->m_SimulatedPlayerToggleableBlocks; + m_LinkedPoweredBlocks = &m_RedstoneSimulatorChunkData->m_LinkedBlocks; m_Chunk = a_Chunk; bool ShouldUpdateSimulateOnceBlocks = false; @@ -240,11 +559,11 @@ void cIncrementalRedstoneSimulatorbegin(); dataitr != m_RedstoneSimulatorChunkData->end();) + for (cCoordWithBlockAndBoolVector::iterator dataitr = m_RedstoneSimulatorChunkData->m_ChunkData.begin(); dataitr != m_RedstoneSimulatorChunkData->m_ChunkData.end();) { if (dataitr->DataTwo) { - dataitr = m_RedstoneSimulatorChunkData->erase(dataitr); + dataitr = m_RedstoneSimulatorChunkData->m_ChunkData.erase(dataitr); continue; } @@ -1497,7 +1816,7 @@ bool cIncrementalRedstoneSimulatorGetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; - for (typename PoweredBlocksList::const_iterator itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end(); ++itr) // Check powered list + for (typename PoweredBlocksList::const_iterator itr = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.begin(); itr != ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.end(); ++itr) // Check powered list { if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { @@ -1904,8 +2223,8 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorPoweredBlocksList(); // We need to insert the value into the chunk who owns the block position - for (typename PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) + PoweredBlocksList & Powered = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)Neighbour->GetRedstoneSimulatorData())->m_PoweredBlocks; // We need to insert the value into the chunk who owns the block position + for (typename PoweredBlocksList::iterator itr = Powered.begin(); itr != Powered.end(); ++itr) { if ( itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && @@ -1952,7 +2271,7 @@ void cIncrementalRedstoneSimulatorpush_back(RC); + Powered.push_back(RC); Neighbour->SetIsRedstoneDirty(true); m_Chunk->SetIsRedstoneDirty(true); } @@ -1986,8 +2305,8 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorLinkedBlocksList(); - for (typename LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list + LinkedBlocksList & Linked = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)Neighbour->GetRedstoneSimulatorData())->m_LinkedBlocks; + for (typename LinkedBlocksList::iterator itr = Linked.begin(); itr != Linked.end(); ++itr) // Check linked powered list { if ( itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) && @@ -2006,7 +2325,7 @@ void cIncrementalRedstoneSimulatorpush_back(RC); + Linked.push_back(RC); Neighbour->SetIsRedstoneDirty(true); m_Chunk->SetIsRedstoneDirty(true); } @@ -2096,21 +2415,21 @@ void cIncrementalRedstoneSimulatorGetRedstoneSimulatorPoweredBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->end();) + for (typename PoweredBlocksList::iterator itr = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.begin(); itr != ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.end();) { if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) { - itr = a_Chunk->GetRedstoneSimulatorPoweredBlocksList()->erase(itr); + itr = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks.erase(itr); a_Chunk->SetIsRedstoneDirty(true); continue; } ++itr; } - for (typename LinkedBlocksList::iterator itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->begin(); itr != a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->end();) + for (typename LinkedBlocksList::iterator itr = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.begin(); itr != ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.end();) { if (itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))) { - itr = a_Chunk->GetRedstoneSimulatorLinkedBlocksList()->erase(itr); + itr = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_LinkedBlocks.erase(itr); a_Chunk->SetIsRedstoneDirty(true); continue; } diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 56843e37f..0e3dd495d 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -4,6 +4,12 @@ #include "Simulator.h" +class cRedstoneSimulatorChunkData +{ +public: + virtual ~cRedstoneSimulatorChunkData() {} +} ; + template class cRedstoneSimulator : diff --git a/src/World.cpp b/src/World.cpp index 732c9f14c..ded42f093 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3272,7 +3272,7 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFil if (NoCaseCompare(SimulatorName, "Incremental") == 0) { - res = new cIncrementalRedstoneSimulator(*this); + res = MakeIncrementalRedstoneSimulator(*this); } else if (NoCaseCompare(SimulatorName, "noop") == 0) { -- cgit v1.2.3 From 3406957f1b4b6b49c1b571dcceb2b463def9e4c3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 09:38:06 +0200 Subject: Initial BungeeCord support. Ref.: #1392 --- src/Protocol/Protocol17x.cpp | 9 +++++++++ src/Protocol/ProtocolRecognizer.cpp | 2 +- src/StringUtils.cpp | 28 ++++++++++++++++++++++++++++ src/StringUtils.h | 5 +++++ 4 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f07f6a928..9ebb6b4b0 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -100,6 +100,15 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd m_IsEncrypted(false), m_LastSentDimension(dimNotSet) { + // BungeeCord handling: + // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: + // hostname\00ip-address\00uuid\00profile-properties-as-json + AStringVector Params; + if (SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) + { + m_ServerAddress = Params[0]; + } + // Create the comm log file, if so requested: if (g_ShouldLogCommIn || g_ShouldLogCommOut) { diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 8b395230a..d836291c3 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -27,7 +27,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : super(a_Client), m_Protocol(NULL), - m_Buffer(512) + m_Buffer(8192) // We need a larger buffer to support BungeeCord - it sends one huge packet at the start { } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 5f88cbf64..73147eebc 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -869,3 +869,31 @@ void SetBEInt(char * a_Mem, Int32 a_Value) + +bool SplitZeroTerminatedStrings(const AString & a_Strings, AStringVector & a_Output) +{ + a_Output.clear(); + size_t size = a_Strings.size(); + size_t start = 0; + bool res = false; + for (size_t i = 0; i < size; i++) + { + if (a_Strings[i] == 0) + { + a_Output.push_back(a_Strings.substr(start, i - start)); + start = i + 1; + res = true; + } + } + if (start < size) + { + a_Output.push_back(a_Strings.substr(start, size - start)); + res = true; + } + + return res; +} + + + + diff --git a/src/StringUtils.h b/src/StringUtils.h index 72a90a8c2..a76894d05 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -99,6 +99,11 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); +/** Splits a string that has embedded \0 characters, on those characters. +a_Output is first cleared and then each separate string is pushed back into a_Output. +Returns true if there are at least two strings in a_Output (there was at least one \0 separator). */ +extern bool SplitZeroTerminatedStrings(const AString & a_Strings, AStringVector & a_Output); + /// Parses any integer type. Checks bounds and returns errors out of band. template bool StringToInteger(const AString & a_str, T & a_Num) -- cgit v1.2.3 From 82317709f8645642069c1ddf3428a0341302fcd4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 11:07:42 +0200 Subject: Full BungeeCord compatibility. Fixes #1392. Fixes SpigotMC/BungeeCord#1211. --- src/ClientHandle.h | 14 +++++++++++++- src/Protocol/Protocol17x.cpp | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 74e89deee..3d0995636 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -64,15 +64,27 @@ public: const AString & GetIPString(void) const { return m_IPString; } // tolua_export + /** Sets the IP string that the client is using. Overrides the IP string that was read from the socket. + Used mainly by BungeeCord compatibility code. */ + void SetIPString(const AString & a_IPString) { m_IPString = a_IPString; } + cPlayer * GetPlayer(void) { return m_Player; } // tolua_export /** Returns the player's UUID, as used by the protocol, in the short form (no dashes) */ const AString & GetUUID(void) const { return m_UUID; } // tolua_export - void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; } + /** Sets the player's UUID, as used by the protocol. Short UUID form (no dashes) is expected. + Used mainly by BungeeCord compatibility code - when authenticating is done on the BungeeCord server + and the results are passed to MCS running in offline mode. */ + void SetUUID(const AString & a_UUID) { ASSERT(a_UUID.size() == 32); m_UUID = a_UUID; } const Json::Value & GetProperties(void) const { return m_Properties; } + /** Sets the player's properties, such as skin image and signature. + Used mainly by BungeeCord compatibility code - property querying is done on the BungeeCord server + and the results are passed to MCS running in offline mode. */ + void SetProperties(const Json::Value & a_Properties) { m_Properties = a_Properties; } + /** Generates an UUID based on the username stored for this client, and stores it in the m_UUID member. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9ebb6b4b0..4f71b53b0 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -106,7 +106,11 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd AStringVector Params; if (SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) { + LOGD("Player at %s connected via BungeeCord", Params[1].c_str()); m_ServerAddress = Params[0]; + m_Client->SetIPString(Params[1]); + m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); + m_Client->SetProperties(Params[3]); } // Create the comm log file, if so requested: -- cgit v1.2.3 From 010879e43f591726809800b45d783d247508daa1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 16:01:14 +0200 Subject: BungeeCord compatibility: don't overwrite UUID / properties. --- src/ClientHandle.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 170498037..4a3a3c250 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -312,8 +312,16 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, ASSERT(m_Player == NULL); m_Username = a_Name; - m_UUID = a_UUID; - m_Properties = a_Properties; + + // Only assign UUID and properties if not already pre-assigned (BungeeCord sends those in the Handshake packet): + if (m_UUID.empty()) + { + m_UUID = a_UUID; + } + if (m_Properties.empty()) + { + m_Properties = a_Properties; + } // Send login success (if the protocol supports it): m_Protocol->SendLoginSuccess(); -- cgit v1.2.3 From c63e14b6d11a97b56e17d628aebdd5e244999a15 Mon Sep 17 00:00:00 2001 From: nesco Date: Wed, 17 Sep 2014 17:15:47 +0200 Subject: Preparing 1.8 update --- src/Entities/Player.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0f15ba620..660ad3239 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -451,6 +451,11 @@ void cPlayer::CancelChargingBow(void) void cPlayer::SetTouchGround(bool a_bTouchGround) { + if (IsGameModeSpectator()) // You can fly through the ground in survival + { + return; + } + m_bTouchGround = a_bTouchGround; if (!m_bTouchGround) @@ -585,7 +590,7 @@ bool cPlayer::Feed(int a_Food, double a_Saturation) void cPlayer::AddFoodExhaustion(double a_Exhaustion) { - if (!IsGameModeCreative()) + if (!(IsGameModeCreative() || IsGameModeSpectator())) { m_FoodExhaustionLevel = std::min(m_FoodExhaustionLevel + a_Exhaustion, 40.0); } @@ -823,9 +828,9 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin)) { - if (IsGameModeCreative()) + if (IsGameModeCreative() || IsGameModeSpectator()) { - // No damage / health in creative mode if not void or plugin damage + // No damage / health in creative or spectator mode if not void or plugin damage return false; } } @@ -1348,7 +1353,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos) void cPlayer::SetVisible(bool a_bVisible) { - // Need to Check if this or other players are in gamemode spectator + // Need to Check if the player or other players are in gamemode spectator, but will break compatibility if (a_bVisible && !m_bVisible) // Make visible { m_bVisible = true; @@ -1509,6 +1514,11 @@ void cPlayer::TossPickup(const cItem & a_Item) void cPlayer::TossItems(const cItems & a_Items) { + if (IsGameModeSpectator()) // Players can't toss items in spectator + { + return; + } + m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size()); double vX = 0, vY = 0, vZ = 0; @@ -1795,7 +1805,7 @@ bool cPlayer::SaveToDisk() void cPlayer::UseEquippedItem(int a_Amount) { - if (IsGameModeCreative()) // No damage in creative + if (IsGameModeCreative() || IsGameModeSpectator()) // No damage in creative or spectator { return; } -- cgit v1.2.3 From b70e09bc90ce28d9397de75ea80bdb669dfbf4ef Mon Sep 17 00:00:00 2001 From: nesco Date: Wed, 17 Sep 2014 17:32:37 +0200 Subject: Update World.h --- src/World.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/World.h b/src/World.h index 6f680694f..8b40037af 100644 --- a/src/World.h +++ b/src/World.h @@ -189,7 +189,7 @@ public: bool IsGameModeAdventure(void) const { return (m_GameMode == gmAdventure); } /** Returns true if the world is in Spectator mode */ - bool IsGameModeAdventure(void) const { return (m_GameMode == gmSpectator); } + bool IsGameModeSpectator(void) const { return (m_GameMode == gmSpectator); } bool IsPVPEnabled(void) const { return m_bEnabledPVP; } bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; } -- cgit v1.2.3 From 3ee211bbbaa4673b2f38846fadb1d2bfba93b1a3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 17 Sep 2014 17:53:42 +0200 Subject: Use xofts ReadPosition() code. --- src/ByteBuffer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 851c63858..262e0e3b5 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -497,9 +497,12 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) return false; } - a_BlockX = Value >> 38; - a_BlockY = Value << 26 >> 52; - a_BlockZ = Value << 38 >> 38; + UInt32 BlockXRaw = (Value >> 38) & 0x3ffffff; + UInt32 BlockYRaw = (Value >> 26) & 0xfff; + UInt32 BlockZRaw = (Value & 0x3ffffff); + a_BlockX = ((BlockXRaw & 0x2000000) == 0) ? BlockXRaw : (~(BlockXRaw & 0x1ffffff)) + 1; + a_BlockY = ((BlockYRaw & 0x800) == 0) ? BlockYRaw : (~(BlockXRaw & 0x7ff)) + 1; + a_BlockZ = ((BlockZRaw & 0x2000000) == 0) ? BlockZRaw : (~(BlockZRaw & 0x1ffffff)) + 1; return true; } -- cgit v1.2.3 From 6e7c0e33b5dd6d86d66ac2eb1a07a33652a708fd Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 17 Sep 2014 18:40:10 +0100 Subject: Added first test to show the object can be created --- src/Bindings/CMakeLists.txt | 2 + src/BlockEntities/DispenserEntity.cpp | 2 +- src/BlockID.cpp | 56 ++++++------ src/BlockInfo.cpp | 42 --------- src/BlockInfo.h | 31 ++++++- src/Blocks/BlockMobHead.h | 4 +- src/Blocks/BlockPiston.h | 2 +- src/Blocks/BlockPortal.h | 2 +- src/Blocks/BlockPumpkin.h | 6 +- src/Blocks/ChunkInterface.cpp | 66 ++++++++++++++ src/Blocks/ChunkInterface.h | 63 +++----------- src/Blocks/WorldInterface.h | 7 +- src/Entities/Entity.cpp | 20 ++--- src/Entities/EntityEffect.cpp | 4 +- src/Entities/Player.cpp | 4 +- src/Entities/ThrownEggEntity.cpp | 10 +-- src/Entities/ThrownSnowballEntity.cpp | 4 +- src/Generating/FinishGen.cpp | 1 + src/Globals.h | 21 +++++ src/Items/ItemSpawnEgg.h | 56 ++++++------ src/MobSpawner.cpp | 100 ++++++++++----------- src/MobSpawner.h | 12 +-- src/Mobs/AggressiveMonster.cpp | 2 +- src/Mobs/AggressiveMonster.h | 2 +- src/Mobs/Monster.cpp | 116 ++++++++++++------------- src/Mobs/Monster.h | 54 ++---------- src/Mobs/MonsterTypes.h | 41 +++++++++ src/Mobs/Mooshroom.cpp | 2 +- src/Mobs/PassiveAggressiveMonster.cpp | 2 +- src/Mobs/PassiveAggressiveMonster.h | 2 +- src/Mobs/PassiveMonster.cpp | 2 +- src/Mobs/PassiveMonster.h | 2 +- src/Protocol/Protocol125.cpp | 32 +++---- src/Protocol/Protocol17x.cpp | 30 +++---- src/Simulator/IncrementalRedstoneSimulator.cpp | 4 +- src/Simulator/IncrementalRedstoneSimulator.inc | 55 +++++++----- src/Simulator/SandSimulator.cpp | 1 + src/Simulator/Simulator.cpp | 5 ++ src/Simulator/Simulator.h | 1 - src/Simulator/Simulator.inc | 4 - src/World.cpp | 6 +- src/World.h | 4 +- src/WorldStorage/NBTChunkSerializer.cpp | 82 ++++++++--------- 43 files changed, 508 insertions(+), 456 deletions(-) create mode 100644 src/Mobs/MonsterTypes.h (limited to 'src') diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 7a1769e9a..930ee9771 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -129,6 +129,8 @@ set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPER set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE) +set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error) + if(NOT MSVC) add_library(Bindings ${SRCS} ${HDRS}) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index c02c68afa..d3c06653f 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -109,7 +109,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, (cMonster::eType)m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0) + if (m_World->SpawnMob(MobX, DispY, MobZ, (eMonsterType)m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } diff --git a/src/BlockID.cpp b/src/BlockID.cpp index 07a1fc9e5..9026d81f2 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -261,34 +261,34 @@ int StringToMobType(const AString & a_MobString) const char * m_String; } MobMap [] = { - {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"}, + {mtCreeper, "Creeper"}, + {mtSkeleton, "Skeleton"}, + {mtSpider, "Spider"}, + {mtGiant, "Giant"}, + {mtZombie, "Zombie"}, + {mtSlime, "Slime"}, + {mtGhast, "Ghast"}, + {mtZombiePigman, "ZombiePigman"}, + {mtEnderman, "Enderman"}, + {mtCaveSpider, "CaveSpider"}, + {mtSilverfish, "SilverFish"}, + {mtBlaze, "Blaze"}, + {mtMagmaCube, "MagmaCube"}, + {mtEnderDragon, "EnderDragon"}, + {mtWither, "Wither"}, + {mtBat, "Bat"}, + {mtWitch, "Witch"}, + {mtPig, "Pig"}, + {mtSheep, "Sheep"}, + {mtCow, "Cow"}, + {mtChicken, "Chicken"}, + {mtSquid, "Squid"}, + {mtWolf, "Wolf"}, + {mtMooshroom, "Mooshroom"}, + {mtSnowGolem, "SnowGolem"}, + {mtOcelot, "Ocelot"}, + {mtIronGolem, "IronGolem"}, + {mtVillager, "Villager"}, }; for (size_t i = 0; i < ARRAYCOUNT(MobMap); i++) { diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 9ac66d35d..12eeceba2 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -6,26 +6,6 @@ - - -cBlockInfo::cBlockInfo() - : m_LightValue(0x00) - , m_SpreadLightFalloff(0x0f) - , m_Transparent(false) - , m_OneHitDig(false) - , m_PistonBreakable(false) - , m_IsSnowable(false) - , m_IsSolid(true) - , m_FullyOccupiesVoxel(false) - , m_CanBeTerraformed(false) - , m_PlaceSound("") - , m_Handler(NULL) -{} - - - - - cBlockInfo::~cBlockInfo() { delete m_Handler; @@ -33,28 +13,6 @@ cBlockInfo::~cBlockInfo() } - - - -/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. -It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. -It works only if it is called for the first time before the app spawns other threads. */ -cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) -{ - static cBlockInfo ms_Info[256]; - static bool IsBlockInfoInitialized = false; - if (!IsBlockInfoInitialized) - { - cBlockInfo::Initialize(ms_Info); - IsBlockInfoInitialized = true; - } - return ms_Info[a_Type]; -} - - - - - void cBlockInfo::Initialize(cBlockInfoArray & a_Info) { for (unsigned int i = 0; i < 256; ++i) diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 567070a7f..bfa62a132 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -11,14 +11,27 @@ class cBlockHandler; - // tolua_begin class cBlockInfo { public: /** Returns the associated BlockInfo structure for the specified block type. */ - static cBlockInfo & Get(BLOCKTYPE a_Type); + + /** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. +It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. +It works only if it is called for the first time before the app spawns other threads. */ + static cBlockInfo & Get(BLOCKTYPE a_Type) + { + static cBlockInfo ms_Info[256]; + static bool IsBlockInfoInitialized = false; + if (!IsBlockInfoInitialized) + { + cBlockInfo::Initialize(ms_Info); + IsBlockInfoInitialized = true; + } + return ms_Info[a_Type]; + } /** How much light do the blocks emit on their own? */ @@ -78,7 +91,19 @@ protected: typedef cBlockInfo cBlockInfoArray[256]; /** Creates a default BlockInfo structure, initializes all values to their defaults */ - cBlockInfo(); + cBlockInfo() + : m_LightValue(0x00) + , m_SpreadLightFalloff(0x0f) + , m_Transparent(false) + , m_OneHitDig(false) + , m_PistonBreakable(false) + , m_IsSnowable(false) + , m_IsSolid(true) + , m_FullyOccupiesVoxel(false) + , m_CanBeTerraformed(false) + , m_PlaceSound("") + , m_Handler(NULL) + {} /** Cleans up the stored values */ ~cBlockInfo(); diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index ff1ef97bf..f19c78694 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -151,7 +151,7 @@ public: a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); // Spawn the wither: - a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither); // Award Achievement a_WorldInterface.ForEachPlayer(PlayerCallback); @@ -181,7 +181,7 @@ public: a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); // Spawn the wither: - a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither); // Award Achievement a_WorldInterface.ForEachPlayer(PlayerCallback); diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 0bec603e3..78959595b 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -4,7 +4,7 @@ #include "BlockHandler.h" - +class cWorld; class cBlockPistonHandler : diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index 8fac2a126..97ba26ee3 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -50,7 +50,7 @@ public: int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX; int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ; - a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman); + a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, mtZombiePigman); } virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 15ac80fd7..275d1422a 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -36,7 +36,7 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); - a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtSnowGolem); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtSnowGolem); return; } @@ -61,7 +61,7 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Spawn the golem: - a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem); } else if ( (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) == E_BLOCK_IRON_BLOCK) && @@ -76,7 +76,7 @@ public: a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); // Spawn the golem: - a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem); + a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem); } } diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index 540581ae7..809c24635 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -2,8 +2,74 @@ #include "Globals.h" #include "ChunkInterface.h" +#include "ChunkMap.h" #include "BlockHandler.h" +BLOCKTYPE cChunkInterface::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ); +} +BLOCKTYPE cChunkInterface::GetBlock(const Vector3i & a_Pos) +{ + return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z); +} +NIBBLETYPE cChunkInterface::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); +} + +bool cChunkInterface::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +{ + return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); +} + +/** Sets the block at the specified coords to the specified value. +Full processing, incl. updating neighbors, is performed. +*/ +void cChunkInterface::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); +} + +void cChunkInterface::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) +{ + m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData); +} + +void cChunkInterface::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface) +{ + m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType); +} + +/** Sets the block at the specified coords to the specified value. +The replacement doesn't trigger block updates. +The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block) +*/ +void cChunkInterface::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); +} + +void cChunkInterface::FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); +} + +void cChunkInterface::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); +} + +bool cChunkInterface::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) +{ + return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback); +} + +bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) +{ + return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes); +} + bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z) { cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index dea9d7c7e..dff30a6ee 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -1,13 +1,12 @@ #pragma once -#include "../ChunkMap.h" #include "../ForEachChunkProvider.h" #include "WorldInterface.h" - +class cChunkMap; class cChunkInterface: public cForEachChunkProvider @@ -16,70 +15,34 @@ public: cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {} - BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) - { - return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - } - BLOCKTYPE GetBlock(const Vector3i & a_Pos) - { - return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z); - } - NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) - { - return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - } + BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ); + BLOCKTYPE GetBlock(const Vector3i & a_Pos); + NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ); - bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) - { - return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - } + bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ - void SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) - { - m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - } + void SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) - { - m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData); - } + void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData); - void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface) - { - m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType); - } + void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface); /** Sets the block at the specified coords to the specified value. The replacement doesn't trigger block updates. The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block) */ - void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) - { - m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - } + void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) - { - FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); - } + void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) - { - m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); - } + void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); - virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override - { - return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback); - } + virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override; - virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override - { - return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes); - } + virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override; bool DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z); diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index b43d011d8..27e06fff3 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -2,14 +2,15 @@ #pragma once #include "BroadcastInterface.h" -#include "../Mobs/Monster.h" +#include "../Mobs/MonsterTypes.h" class cItems; typedef cItemCallback cBlockEntityCallback; - +class cMonster; +class cPlayer; class cWorldInterface @@ -33,7 +34,7 @@ public: virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0; /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ - virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; + virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) = 0; /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 9bcdcffeb..4581eeda8 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -334,10 +334,10 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) cMonster * Monster = (cMonster *)this; switch (Monster->GetMobType()) { - case cMonster::mtSkeleton: - case cMonster::mtZombie: - case cMonster::mtWither: - case cMonster::mtZombiePigman: + case mtSkeleton: + case mtZombie: + case mtWither: + case mtZombiePigman: { a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel); break; @@ -352,9 +352,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) cMonster * Monster = (cMonster *)this; switch (Monster->GetMobType()) { - case cMonster::mtSpider: - case cMonster::mtCaveSpider: - case cMonster::mtSilverfish: + case mtSpider: + case mtCaveSpider: + case mtSilverfish: { a_TDI.RawDamage += (int)ceil(2.5 * BaneOfArthropodsLevel); // TODO: Add slowness effect @@ -384,9 +384,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) cMonster * Monster = (cMonster *)this; switch (Monster->GetMobType()) { - case cMonster::mtGhast: - case cMonster::mtZombiePigman: - case cMonster::mtMagmaCube: + case mtGhast: + case mtZombiePigman: + case mtMagmaCube: { break; }; diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index f08755674..8235275a6 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -349,8 +349,8 @@ void cEntityEffectPoison::OnTick(cPawn & a_Target) // Doesn't effect undead mobs, spiders if ( Target.IsUndead() || - (Target.GetMobType() == cMonster::mtSpider) || - (Target.GetMobType() == cMonster::mtCaveSpider) + (Target.GetMobType() == mtSpider) || + (Target.GetMobType() == mtCaveSpider) ) { return; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index b0da6965a..4458cd32f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2003,8 +2003,8 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) cMonster * Monster = (cMonster *)m_AttachedTo; switch (Monster->GetMobType()) { - case cMonster::mtPig: m_Stats.AddValue(statDistPig, Value); break; - case cMonster::mtHorse: m_Stats.AddValue(statDistHorse, Value); break; + case mtPig: m_Stats.AddValue(statDistPig, Value); break; + case mtHorse: m_Stats.AddValue(statDistHorse, Value); break; default: break; } break; diff --git a/src/Entities/ThrownEggEntity.cpp b/src/Entities/ThrownEggEntity.cpp index 456083108..5ae85bee8 100644 --- a/src/Entities/ThrownEggEntity.cpp +++ b/src/Entities/ThrownEggEntity.cpp @@ -48,13 +48,13 @@ void cThrownEggEntity::TrySpawnChicken(const Vector3d & a_HitPos) { if (m_World->GetTickRandomNumber(7) == 1) { - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, cMonster::mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); } else if (m_World->GetTickRandomNumber(32) == 1) { - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, cMonster::mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, cMonster::mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, cMonster::mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, cMonster::mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); } } diff --git a/src/Entities/ThrownSnowballEntity.cpp b/src/Entities/ThrownSnowballEntity.cpp index d94e75898..496397100 100644 --- a/src/Entities/ThrownSnowballEntity.cpp +++ b/src/Entities/ThrownSnowballEntity.cpp @@ -32,8 +32,8 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & int TotalDamage = 0; if (a_EntityHit.IsMob()) { - cMonster::eType MobType = ((cMonster &) a_EntityHit).GetMobType(); - if (MobType == cMonster::mtBlaze) + eMonsterType MobType = ((cMonster &) a_EntityHit).GetMobType(); + if (MobType == mtBlaze) { TotalDamage = 3; } diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index eb57a5faa..96e3dc26b 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -15,6 +15,7 @@ #include "../Simulator/FluidSimulator.h" // for cFluidSimulator::CanWashAway() #include "../Simulator/FireSimulator.h" #include "../World.h" +#include "inifile/iniFile.h" diff --git a/src/Globals.h b/src/Globals.h index de1024010..c75c4e99b 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -261,6 +261,27 @@ void inline LOGERROR(const char* a_Format, ...) vprintf(a_Format, argList); va_end(argList); } + +void inline LOGWARNING(const char* a_Format, ...) FORMATSTRING(1, 2); + +void inline LOGWARNING(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + va_end(argList); +} + +void inline LOGD(const char* a_Format, ...) FORMATSTRING(1, 2); + +void inline LOGD(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + va_end(argList); +} + #endif diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h index bba97afa1..617ecd808 100644 --- a/src/Items/ItemSpawnEgg.h +++ b/src/Items/ItemSpawnEgg.h @@ -33,9 +33,9 @@ public: a_BlockY--; } - cMonster::eType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage); + eMonsterType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage); if ( - (MonsterType != cMonster::mtInvalidType) && // Valid monster type + (MonsterType != mtInvalidType) && // Valid monster type (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) >= 0)) // Spawning succeeded { if (!a_Player->IsGameModeCreative()) @@ -52,36 +52,36 @@ public: /** Converts the Spawn egg item damage to the monster type to spawn. Returns mtInvalidType for invalid damage values. */ - static cMonster::eType ItemDamageToMonsterType(short a_ItemDamage) + static eMonsterType ItemDamageToMonsterType(short a_ItemDamage) { switch (a_ItemDamage) { - case E_META_SPAWN_EGG_BAT: return cMonster::mtBat; - case E_META_SPAWN_EGG_BLAZE: return cMonster::mtBlaze; - case E_META_SPAWN_EGG_CAVE_SPIDER: return cMonster::mtCaveSpider; - case E_META_SPAWN_EGG_CHICKEN: return cMonster::mtChicken; - case E_META_SPAWN_EGG_COW: return cMonster::mtCow; - case E_META_SPAWN_EGG_CREEPER: return cMonster::mtCreeper; - case E_META_SPAWN_EGG_ENDERMAN: return cMonster::mtEnderman; - case E_META_SPAWN_EGG_GHAST: return cMonster::mtGhast; - case E_META_SPAWN_EGG_HORSE: return cMonster::mtHorse; - case E_META_SPAWN_EGG_MAGMA_CUBE: return cMonster::mtMagmaCube; - case E_META_SPAWN_EGG_MOOSHROOM: return cMonster::mtMooshroom; - case E_META_SPAWN_EGG_OCELOT: return cMonster::mtOcelot; - case E_META_SPAWN_EGG_PIG: return cMonster::mtPig; - case E_META_SPAWN_EGG_SHEEP: return cMonster::mtSheep; - case E_META_SPAWN_EGG_SILVERFISH: return cMonster::mtSilverfish; - case E_META_SPAWN_EGG_SKELETON: return cMonster::mtSkeleton; - case E_META_SPAWN_EGG_SLIME: return cMonster::mtSlime; - case E_META_SPAWN_EGG_SPIDER: return cMonster::mtSpider; - case E_META_SPAWN_EGG_SQUID: return cMonster::mtSquid; - case E_META_SPAWN_EGG_VILLAGER: return cMonster::mtVillager; - case E_META_SPAWN_EGG_WITCH: return cMonster::mtWitch; - case E_META_SPAWN_EGG_WOLF: return cMonster::mtWolf; - case E_META_SPAWN_EGG_ZOMBIE: return cMonster::mtZombie; - case E_META_SPAWN_EGG_ZOMBIE_PIGMAN: return cMonster::mtZombiePigman; + case E_META_SPAWN_EGG_BAT: return mtBat; + case E_META_SPAWN_EGG_BLAZE: return mtBlaze; + case E_META_SPAWN_EGG_CAVE_SPIDER: return mtCaveSpider; + case E_META_SPAWN_EGG_CHICKEN: return mtChicken; + case E_META_SPAWN_EGG_COW: return mtCow; + case E_META_SPAWN_EGG_CREEPER: return mtCreeper; + case E_META_SPAWN_EGG_ENDERMAN: return mtEnderman; + case E_META_SPAWN_EGG_GHAST: return mtGhast; + case E_META_SPAWN_EGG_HORSE: return mtHorse; + case E_META_SPAWN_EGG_MAGMA_CUBE: return mtMagmaCube; + case E_META_SPAWN_EGG_MOOSHROOM: return mtMooshroom; + case E_META_SPAWN_EGG_OCELOT: return mtOcelot; + case E_META_SPAWN_EGG_PIG: return mtPig; + case E_META_SPAWN_EGG_SHEEP: return mtSheep; + case E_META_SPAWN_EGG_SILVERFISH: return mtSilverfish; + case E_META_SPAWN_EGG_SKELETON: return mtSkeleton; + case E_META_SPAWN_EGG_SLIME: return mtSlime; + case E_META_SPAWN_EGG_SPIDER: return mtSpider; + case E_META_SPAWN_EGG_SQUID: return mtSquid; + case E_META_SPAWN_EGG_VILLAGER: return mtVillager; + case E_META_SPAWN_EGG_WITCH: return mtWitch; + case E_META_SPAWN_EGG_WOLF: return mtWolf; + case E_META_SPAWN_EGG_ZOMBIE: return mtZombie; + case E_META_SPAWN_EGG_ZOMBIE_PIGMAN: return mtZombiePigman; } - return cMonster::mtInvalidType; + return mtInvalidType; } } ; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index db05b70af..ea3fe8c72 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -8,12 +8,12 @@ -cMobSpawner::cMobSpawner(cMonster::eFamily a_MonsterFamily, const std::set& a_AllowedTypes) : +cMobSpawner::cMobSpawner(cMonster::eFamily a_MonsterFamily, const std::set& a_AllowedTypes) : m_MonsterFamily(a_MonsterFamily), m_NewPack(true), - m_MobType(cMonster::mtInvalidType) + m_MobType(mtInvalidType) { - for (std::set::const_iterator itr = a_AllowedTypes.begin(); itr != a_AllowedTypes.end(); ++itr) + for (std::set::const_iterator itr = a_AllowedTypes.begin(); itr != a_AllowedTypes.end(); ++itr) { if (cMonster::FamilyFromType(*itr) == a_MonsterFamily) { @@ -44,9 +44,9 @@ bool cMobSpawner::CheckPackCenter(BLOCKTYPE a_BlockType) -void cMobSpawner::addIfAllowed(cMonster::eType toAdd, std::set& toAddIn) +void cMobSpawner::addIfAllowed(eMonsterType toAdd, std::set& toAddIn) { - std::set::iterator itr = m_AllowedTypes.find(toAdd); + std::set::iterator itr = m_AllowedTypes.find(toAdd); if (itr != m_AllowedTypes.end()) { toAddIn.insert(toAdd); @@ -57,49 +57,49 @@ void cMobSpawner::addIfAllowed(cMonster::eType toAdd, std::set& -cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) +eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) { - std::set allowedMobs; + std::set allowedMobs; if (a_Biome == biMushroomIsland || a_Biome == biMushroomShore) { - addIfAllowed(cMonster::mtMooshroom, allowedMobs); + addIfAllowed(mtMooshroom, allowedMobs); } else if (a_Biome == biNether) { - addIfAllowed(cMonster::mtGhast, allowedMobs); - addIfAllowed(cMonster::mtZombiePigman, allowedMobs); - addIfAllowed(cMonster::mtMagmaCube, allowedMobs); + addIfAllowed(mtGhast, allowedMobs); + addIfAllowed(mtZombiePigman, allowedMobs); + addIfAllowed(mtMagmaCube, allowedMobs); } else if (a_Biome == biEnd) { - addIfAllowed(cMonster::mtEnderman, allowedMobs); + addIfAllowed(mtEnderman, allowedMobs); } else { - addIfAllowed(cMonster::mtBat, allowedMobs); - addIfAllowed(cMonster::mtSpider, allowedMobs); - addIfAllowed(cMonster::mtZombie, allowedMobs); - addIfAllowed(cMonster::mtSkeleton, allowedMobs); - addIfAllowed(cMonster::mtCreeper, allowedMobs); - addIfAllowed(cMonster::mtSquid, allowedMobs); + addIfAllowed(mtBat, allowedMobs); + addIfAllowed(mtSpider, allowedMobs); + addIfAllowed(mtZombie, allowedMobs); + addIfAllowed(mtSkeleton, allowedMobs); + addIfAllowed(mtCreeper, allowedMobs); + addIfAllowed(mtSquid, allowedMobs); if (a_Biome != biDesert && a_Biome != biBeach && a_Biome != biOcean) { - addIfAllowed(cMonster::mtSheep, allowedMobs); - addIfAllowed(cMonster::mtPig, allowedMobs); - addIfAllowed(cMonster::mtCow, allowedMobs); - addIfAllowed(cMonster::mtChicken, allowedMobs); - addIfAllowed(cMonster::mtEnderman, allowedMobs); - addIfAllowed(cMonster::mtSlime, allowedMobs); // MG TODO : much more complicated rule + addIfAllowed(mtSheep, allowedMobs); + addIfAllowed(mtPig, allowedMobs); + addIfAllowed(mtCow, allowedMobs); + addIfAllowed(mtChicken, allowedMobs); + addIfAllowed(mtEnderman, allowedMobs); + addIfAllowed(mtSlime, allowedMobs); // MG TODO : much more complicated rule if (a_Biome == biForest || a_Biome == biForestHills || a_Biome == biTaiga || a_Biome == biTaigaHills) { - addIfAllowed(cMonster::mtWolf, allowedMobs); + addIfAllowed(mtWolf, allowedMobs); } else if (a_Biome == biJungle || a_Biome == biJungleHills) { - addIfAllowed(cMonster::mtOcelot, allowedMobs); + addIfAllowed(mtOcelot, allowedMobs); } } } @@ -107,7 +107,7 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) size_t allowedMobsSize = allowedMobs.size(); if (allowedMobsSize > 0) { - std::set::iterator itr = allowedMobs.begin(); + std::set::iterator itr = allowedMobs.begin(); int iRandom = m_Random.NextInt((int)allowedMobsSize, a_Biome); for (int i = 0; i < iRandom; i++) @@ -117,14 +117,14 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) return *itr; } - return cMonster::mtInvalidType; + return mtInvalidType; } -bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome) +bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome) { BLOCKTYPE TargetBlock = E_BLOCK_AIR; if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) @@ -143,21 +143,21 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R switch (a_MobType) { - case cMonster::mtSquid: + case mtSquid: { return IsBlockWater(TargetBlock) && (a_RelY >= 45) && (a_RelY <= 62); } - case cMonster::mtBat: + case mtBat: { return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4) && (TargetBlock == E_BLOCK_AIR) && !cBlockInfo::IsTransparent(BlockAbove); } - case cMonster::mtChicken: - case cMonster::mtCow: - case cMonster::mtPig: - case cMonster::mtHorse: - case cMonster::mtSheep: + case mtChicken: + case mtCow: + case mtPig: + case mtHorse: + case mtSheep: { return ( (TargetBlock == E_BLOCK_AIR) && @@ -168,7 +168,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ); } - case cMonster::mtOcelot: + case mtOcelot: { return ( (TargetBlock == E_BLOCK_AIR) && @@ -181,7 +181,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ); } - case cMonster::mtEnderman: + case mtEnderman: { if (a_RelY < 250) { @@ -202,7 +202,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R break; } - case cMonster::mtSpider: + case mtSpider: { bool CanSpawn = true; bool HasFloor = false; @@ -228,9 +228,9 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return CanSpawn && HasFloor && (SkyLight <= 7) && (BlockLight <= 7); } - case cMonster::mtCreeper: - case cMonster::mtSkeleton: - case cMonster::mtZombie: + case mtCreeper: + case mtSkeleton: + case mtZombie: { return ( (TargetBlock == E_BLOCK_AIR) && @@ -242,8 +242,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ); } - case cMonster::mtMagmaCube: - case cMonster::mtSlime: + case mtMagmaCube: + case mtSlime: { return ( (TargetBlock == E_BLOCK_AIR) && @@ -255,8 +255,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ); } - case cMonster::mtGhast: - case cMonster::mtZombiePigman: + case mtGhast: + case mtZombiePigman: { return ( (TargetBlock == E_BLOCK_AIR) && @@ -266,7 +266,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R ); } - case cMonster::mtWolf: + case mtWolf: { return ( (TargetBlock == E_BLOCK_GRASS) && @@ -305,15 +305,15 @@ cMonster* cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, if (m_NewPack) { m_MobType = ChooseMobType(a_Biome); - if (m_MobType == cMonster::mtInvalidType) + if (m_MobType == mtInvalidType) { return toReturn; } - if (m_MobType == cMonster::mtWolf) + if (m_MobType == mtWolf) { a_MaxPackSize = 8; } - else if (m_MobType == cMonster::mtGhast) + else if (m_MobType == mtGhast) { a_MaxPackSize = 1; } diff --git a/src/MobSpawner.h b/src/MobSpawner.h index f3c56fe2d..6b3a913ec 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -30,7 +30,7 @@ public : // a_AllowedTypes is the set of types allowed for mobs it will spawn. Empty set // would result in no spawn at all // Allowed mobs thah are not of the right Family will not be include (no warning) - cMobSpawner(cMonster::eFamily MobFamily, const std::set & a_AllowedTypes); + cMobSpawner(cMonster::eFamily MobFamily, const std::set & a_AllowedTypes); /// Check if specified block can be a Pack center for this spawner bool CheckPackCenter(BLOCKTYPE a_BlockType); @@ -53,20 +53,20 @@ public : protected : // return true if specified type of mob can spawn on specified block - bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome); + bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome); // return a random type that can spawn on specified biome. // returns E_ENTITY_TYPE_DONOTUSE if none is possible - cMonster::eType ChooseMobType(EMCSBiome a_Biome); + eMonsterType ChooseMobType(EMCSBiome a_Biome); // add toAdd inside toAddIn, if toAdd is in m_AllowedTypes - void addIfAllowed(cMonster::eType toAdd, std::set & toAddIn); + void addIfAllowed(eMonsterType toAdd, std::set & toAddIn); protected : cMonster::eFamily m_MonsterFamily; - std::set m_AllowedTypes; + std::set m_AllowedTypes; bool m_NewPack; - cMonster::eType m_MobType; + eMonsterType m_MobType; std::set m_Spawned; cFastRandom m_Random; } ; diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index 5f5b1853d..be2f71f7a 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -11,7 +11,7 @@ -cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : +cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height) { m_EMPersonality = AGGRESSIVE; diff --git a/src/Mobs/AggressiveMonster.h b/src/Mobs/AggressiveMonster.h index d70ff04a3..2549ba2d3 100644 --- a/src/Mobs/AggressiveMonster.h +++ b/src/Mobs/AggressiveMonster.h @@ -14,7 +14,7 @@ class cAggressiveMonster : public: - cAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); + cAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); virtual void Tick (float a_Dt, cChunk & a_Chunk) override; virtual void InStateChasing(float a_Dt) override; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index f7ee0b0c0..b6e22c0ee 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -24,38 +24,38 @@ The strings need to be lowercase (for more efficient comparisons in StringToMobT */ static const struct { - cMonster::eType m_Type; + eMonsterType m_Type; const char * m_lcName; } g_MobTypeNames[] = { - {cMonster::mtBat, "bat"}, - {cMonster::mtBlaze, "blaze"}, - {cMonster::mtCaveSpider, "cavespider"}, - {cMonster::mtChicken, "chicken"}, - {cMonster::mtCow, "cow"}, - {cMonster::mtCreeper, "creeper"}, - {cMonster::mtEnderman, "enderman"}, - {cMonster::mtEnderDragon, "enderdragon"}, - {cMonster::mtGhast, "ghast"}, - {cMonster::mtHorse, "horse"}, - {cMonster::mtIronGolem, "irongolem"}, - {cMonster::mtMagmaCube, "magmacube"}, - {cMonster::mtMooshroom, "mooshroom"}, - {cMonster::mtOcelot, "ocelot"}, - {cMonster::mtPig, "pig"}, - {cMonster::mtSheep, "sheep"}, - {cMonster::mtSilverfish, "silverfish"}, - {cMonster::mtSkeleton, "skeleton"}, - {cMonster::mtSlime, "slime"}, - {cMonster::mtSnowGolem, "snowgolem"}, - {cMonster::mtSpider, "spider"}, - {cMonster::mtSquid, "squid"}, - {cMonster::mtVillager, "villager"}, - {cMonster::mtWitch, "witch"}, - {cMonster::mtWither, "wither"}, - {cMonster::mtWolf, "wolf"}, - {cMonster::mtZombie, "zombie"}, - {cMonster::mtZombiePigman, "zombiepigman"}, + {mtBat, "bat"}, + {mtBlaze, "blaze"}, + {mtCaveSpider, "cavespider"}, + {mtChicken, "chicken"}, + {mtCow, "cow"}, + {mtCreeper, "creeper"}, + {mtEnderman, "enderman"}, + {mtEnderDragon, "enderdragon"}, + {mtGhast, "ghast"}, + {mtHorse, "horse"}, + {mtIronGolem, "irongolem"}, + {mtMagmaCube, "magmacube"}, + {mtMooshroom, "mooshroom"}, + {mtOcelot, "ocelot"}, + {mtPig, "pig"}, + {mtSheep, "sheep"}, + {mtSilverfish, "silverfish"}, + {mtSkeleton, "skeleton"}, + {mtSlime, "slime"}, + {mtSnowGolem, "snowgolem"}, + {mtSpider, "spider"}, + {mtSquid, "squid"}, + {mtVillager, "villager"}, + {mtWitch, "witch"}, + {mtWither, "wither"}, + {mtWolf, "wolf"}, + {mtZombie, "zombie"}, + {mtZombiePigman, "zombiepigman"}, } ; @@ -65,7 +65,7 @@ static const struct //////////////////////////////////////////////////////////////////////////////// // cMonster: -cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) +cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : super(etMonster, a_Width, a_Height) , m_EMState(IDLE) , m_EMPersonality(AGGRESSIVE) @@ -485,50 +485,50 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI) switch (m_MobType) { // Animals - case cMonster::mtChicken: - case cMonster::mtCow: - case cMonster::mtHorse: - case cMonster::mtPig: - case cMonster::mtSheep: - case cMonster::mtSquid: - case cMonster::mtMooshroom: - case cMonster::mtOcelot: - case cMonster::mtWolf: + case mtChicken: + case mtCow: + case mtHorse: + case mtPig: + case mtSheep: + case mtSquid: + case mtMooshroom: + case mtOcelot: + case mtWolf: { Reward = m_World->GetTickRandomNumber(2) + 1; break; } // Monsters - case cMonster::mtCaveSpider: - case cMonster::mtCreeper: - case cMonster::mtEnderman: - case cMonster::mtGhast: - case cMonster::mtSilverfish: - case cMonster::mtSkeleton: - case cMonster::mtSpider: - case cMonster::mtWitch: - case cMonster::mtZombie: - case cMonster::mtZombiePigman: - case cMonster::mtSlime: - case cMonster::mtMagmaCube: + case mtCaveSpider: + case mtCreeper: + case mtEnderman: + case mtGhast: + case mtSilverfish: + case mtSkeleton: + case mtSpider: + case mtWitch: + case mtZombie: + case mtZombiePigman: + case mtSlime: + case mtMagmaCube: { Reward = 6 + (m_World->GetTickRandomNumber(2)); break; } - case cMonster::mtBlaze: + case mtBlaze: { Reward = 10; break; } // Bosses - case cMonster::mtEnderDragon: + case mtEnderDragon: { Reward = 12000; break; } - case cMonster::mtWither: + case mtWither: { Reward = 50; break; @@ -697,7 +697,7 @@ bool cMonster::IsUndead(void) -AString cMonster::MobTypeToString(cMonster::eType a_MobType) +AString cMonster::MobTypeToString(eMonsterType a_MobType) { // Mob types aren't sorted, so we need to search linearly: for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++) @@ -716,7 +716,7 @@ AString cMonster::MobTypeToString(cMonster::eType a_MobType) -cMonster::eType cMonster::StringToMobType(const AString & a_Name) +eMonsterType cMonster::StringToMobType(const AString & a_Name) { AString lcName = StrToLower(a_Name); @@ -757,7 +757,7 @@ cMonster::eType cMonster::StringToMobType(const AString & a_Name) -cMonster::eFamily cMonster::FamilyFromType(eType a_Type) +cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type) { // Passive-agressive mobs are counted in mob spawning code as passive @@ -822,7 +822,7 @@ int cMonster::GetSpawnDelay(cMonster::eFamily a_MobFamily) -cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType) +cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) { cFastRandom Random; cMonster * toReturn = NULL; diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index cdbd26c09..60bf36c7a 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -6,6 +6,7 @@ #include "../BlockID.h" #include "../Item.h" #include "../Enchantments.h" +#include "MonsterTypes.h" @@ -15,50 +16,13 @@ class cClientHandle; class cWorld; - - // tolua_begin class cMonster : public cPawn { typedef cPawn super; public: - /// This identifies individual monster type, as well as their network type-ID - enum eType - { - mtInvalidType = -1, - - mtBat = E_META_SPAWN_EGG_BAT, - mtBlaze = E_META_SPAWN_EGG_BLAZE, - mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER, - mtChicken = E_META_SPAWN_EGG_CHICKEN, - mtCow = E_META_SPAWN_EGG_COW, - mtCreeper = E_META_SPAWN_EGG_CREEPER, - mtEnderDragon = E_META_SPAWN_EGG_ENDER_DRAGON, - mtEnderman = E_META_SPAWN_EGG_ENDERMAN, - mtGhast = E_META_SPAWN_EGG_GHAST, - mtGiant = E_META_SPAWN_EGG_GIANT, - mtHorse = E_META_SPAWN_EGG_HORSE, - mtIronGolem = E_META_SPAWN_EGG_IRON_GOLEM, - mtMagmaCube = E_META_SPAWN_EGG_MAGMA_CUBE, - mtMooshroom = E_META_SPAWN_EGG_MOOSHROOM, - mtOcelot = E_META_SPAWN_EGG_OCELOT, - mtPig = E_META_SPAWN_EGG_PIG, - mtSheep = E_META_SPAWN_EGG_SHEEP, - mtSilverfish = E_META_SPAWN_EGG_SILVERFISH, - mtSkeleton = E_META_SPAWN_EGG_SKELETON, - mtSlime = E_META_SPAWN_EGG_SLIME, - mtSnowGolem = E_META_SPAWN_EGG_SNOW_GOLEM, - mtSpider = E_META_SPAWN_EGG_SPIDER, - mtSquid = E_META_SPAWN_EGG_SQUID, - mtVillager = E_META_SPAWN_EGG_VILLAGER, - mtWitch = E_META_SPAWN_EGG_WITCH, - mtWither = E_META_SPAWN_EGG_WITHER, - mtWolf = E_META_SPAWN_EGG_WOLF, - mtZombie = E_META_SPAWN_EGG_ZOMBIE, - mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN, - } ; - + enum eFamily { mfHostile = 0, // Spider, Zombies ... @@ -80,7 +44,7 @@ public: a_MobType is the type of the mob (also used in the protocol ( http://wiki.vg/Entities#Mobs 2012_12_22)) a_SoundHurt and a_SoundDeath are assigned into m_SoundHurt and m_SoundDeath, respectively */ - cMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); + cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); CLASS_PROTODEF(cMonster) @@ -96,7 +60,7 @@ public: virtual bool ReachedDestination(void); // tolua_begin - eType GetMobType(void) const {return m_MobType; } + eMonsterType GetMobType(void) const {return m_MobType; } eFamily GetMobFamily(void) const; // tolua_end @@ -146,13 +110,13 @@ public: // tolua_begin /// Translates MobType enum to a string, empty string if unknown - static AString MobTypeToString(eType a_MobType); + static AString MobTypeToString(eMonsterType a_MobType); /// Translates MobType string to the enum, mtInvalidType if not recognized - static eType StringToMobType(const AString & a_MobTypeName); + static eMonsterType StringToMobType(const AString & a_MobTypeName); /// Returns the mob family based on the type - static eFamily FamilyFromType(eType a_MobType); + static eFamily FamilyFromType(eMonsterType a_MobType); /// Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family static int GetSpawnDelay(cMonster::eFamily a_MobFamily); @@ -163,7 +127,7 @@ public: a_MobType is the type of the mob to be created Asserts and returns null if mob type is not specified */ - static cMonster * NewMonsterFromType(eType a_MobType); + static cMonster * NewMonsterFromType(eMonsterType a_MobType); protected: @@ -227,7 +191,7 @@ protected: float m_IdleInterval; float m_DestroyTimer; - eType m_MobType; + eMonsterType m_MobType; AString m_SoundHurt; AString m_SoundDeath; diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h new file mode 100644 index 000000000..7a73e99f4 --- /dev/null +++ b/src/Mobs/MonsterTypes.h @@ -0,0 +1,41 @@ + +#pragma once + +/// This identifies individual monster type, as well as their network type-ID +// tolua_begin +enum eMonsterType +{ + mtInvalidType = -1, + + mtBat = E_META_SPAWN_EGG_BAT, + mtBlaze = E_META_SPAWN_EGG_BLAZE, + mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER, + mtChicken = E_META_SPAWN_EGG_CHICKEN, + mtCow = E_META_SPAWN_EGG_COW, + mtCreeper = E_META_SPAWN_EGG_CREEPER, + mtEnderDragon = E_META_SPAWN_EGG_ENDER_DRAGON, + mtEnderman = E_META_SPAWN_EGG_ENDERMAN, + mtGhast = E_META_SPAWN_EGG_GHAST, + mtGiant = E_META_SPAWN_EGG_GIANT, + mtHorse = E_META_SPAWN_EGG_HORSE, + mtIronGolem = E_META_SPAWN_EGG_IRON_GOLEM, + mtMagmaCube = E_META_SPAWN_EGG_MAGMA_CUBE, + mtMooshroom = E_META_SPAWN_EGG_MOOSHROOM, + mtOcelot = E_META_SPAWN_EGG_OCELOT, + mtPig = E_META_SPAWN_EGG_PIG, + mtSheep = E_META_SPAWN_EGG_SHEEP, + mtSilverfish = E_META_SPAWN_EGG_SILVERFISH, + mtSkeleton = E_META_SPAWN_EGG_SKELETON, + mtSlime = E_META_SPAWN_EGG_SLIME, + mtSnowGolem = E_META_SPAWN_EGG_SNOW_GOLEM, + mtSpider = E_META_SPAWN_EGG_SPIDER, + mtSquid = E_META_SPAWN_EGG_SQUID, + mtVillager = E_META_SPAWN_EGG_VILLAGER, + mtWitch = E_META_SPAWN_EGG_WITCH, + mtWither = E_META_SPAWN_EGG_WITHER, + mtWolf = E_META_SPAWN_EGG_WOLF, + mtZombie = E_META_SPAWN_EGG_ZOMBIE, + mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN, +} ; +// tolua_end + diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 81bd3e3b4..99958720f 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -67,7 +67,7 @@ void cMooshroom::OnRightClicked(cPlayer & a_Player) cItems Drops; Drops.push_back(cItem(E_BLOCK_RED_MUSHROOM, 5, 0)); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); - m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), cMonster::mtCow); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtCow); Destroy(); } break; } diff --git a/src/Mobs/PassiveAggressiveMonster.cpp b/src/Mobs/PassiveAggressiveMonster.cpp index 24501b1ba..e0cc2fd21 100644 --- a/src/Mobs/PassiveAggressiveMonster.cpp +++ b/src/Mobs/PassiveAggressiveMonster.cpp @@ -9,7 +9,7 @@ -cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : +cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height) { m_EMPersonality = PASSIVE; diff --git a/src/Mobs/PassiveAggressiveMonster.h b/src/Mobs/PassiveAggressiveMonster.h index a0da50e8e..72f472281 100644 --- a/src/Mobs/PassiveAggressiveMonster.h +++ b/src/Mobs/PassiveAggressiveMonster.h @@ -13,7 +13,7 @@ class cPassiveAggressiveMonster : typedef cAggressiveMonster super; public: - cPassiveAggressiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); + cPassiveAggressiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; } ; diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 2861d7314..be3043e3d 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -8,7 +8,7 @@ -cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : +cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) : super(a_ConfigName, a_MobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height) { m_EMPersonality = PASSIVE; diff --git a/src/Mobs/PassiveMonster.h b/src/Mobs/PassiveMonster.h index 70574585a..9221d9a6e 100644 --- a/src/Mobs/PassiveMonster.h +++ b/src/Mobs/PassiveMonster.h @@ -13,7 +13,7 @@ class cPassiveMonster : typedef cMonster super; public: - cPassiveMonster(const AString & a_ConfigName, eType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); + cPassiveMonster(const AString & a_ConfigName, eMonsterType a_MobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height); virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index a66c64309..4a69bc1ac 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1946,7 +1946,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) { switch (a_Mob.GetMobType()) { - case cMonster::mtCreeper: + case mtCreeper: { WriteByte(0x10); WriteChar(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up? @@ -1954,25 +1954,25 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); // Lightning-charged? break; } - case cMonster::mtBat: + case mtBat: { WriteByte(0x10); WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); // Upside down? break; } - case cMonster::mtPig: + case mtPig: { WriteByte(0x10); WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); // Saddled? break; } - case cMonster::mtVillager: + case mtVillager: { WriteByte(0x50); WriteInt(((const cVillager &)a_Mob).GetVilType()); // What sort of TESTIFICATE? break; } - case cMonster::mtZombie: + case mtZombie: { WriteByte(0xC); WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); // Baby zombie? @@ -1982,13 +1982,13 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cZombie &)a_Mob).IsConverting() ? 1 : 0); // Converted-but-converting-back zombllager? break; } - case cMonster::mtGhast: + case mtGhast: { WriteByte(0x10); WriteByte(((const cGhast &)a_Mob).IsCharging()); // About to spit a flameball? break; } - case cMonster::mtWolf: + case mtWolf: { Byte WolfStatus = 0; if (((const cWolf &)a_Mob).IsSitting()) @@ -2012,7 +2012,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cWolf &)a_Mob).IsBegging() ? 1 : 0); // Ultra cute mode? break; } - case cMonster::mtSheep: + case mtSheep: { // [1](1111) // [] = Is sheared? () = Color, from 0 to 15 @@ -2028,7 +2028,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(SheepMetadata); break; } - case cMonster::mtEnderman: + case mtEnderman: { WriteByte(0x10); WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); // Block that he stole from your house @@ -2038,19 +2038,19 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cEnderman &)a_Mob).IsScreaming() ? 1 : 0); // Screaming at your face? break; } - case cMonster::mtSkeleton: + case mtSkeleton: { WriteByte(0xD); WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); // It's a skeleton, but it's not break; } - case cMonster::mtWitch: + case mtWitch: { WriteByte(0x15); WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything break; } - case cMonster::mtWither: + case mtWither: { WriteByte(0x54); // Int at index 20 WriteInt((Int32)((const cWither &)a_Mob).GetWitherInvulnerableTicks()); @@ -2058,11 +2058,11 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteFloat((float)(a_Mob.GetHealth())); break; } - case cMonster::mtSlime: - case cMonster::mtMagmaCube: + case mtSlime: + case mtMagmaCube: { WriteByte(0x10); - if (a_Mob.GetMobType() == cMonster::mtSlime) + if (a_Mob.GetMobType() == mtSlime) { WriteByte((Byte)((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME } @@ -2072,7 +2072,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) } break; } - case cMonster::mtHorse: + case mtHorse: { int Flags = 0; if (((const cHorse &)a_Mob).IsTame()) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f24ef320d..ac7a180d4 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2839,7 +2839,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) { switch (a_Mob.GetMobType()) { - case cMonster::mtCreeper: + case mtCreeper: { WriteByte(0x10); WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); @@ -2848,28 +2848,28 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtBat: + case mtBat: { WriteByte(0x10); WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); break; } - case cMonster::mtPig: + case mtPig: { WriteByte(0x10); WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); break; } - case cMonster::mtVillager: + case mtVillager: { WriteByte(0x50); WriteInt(((const cVillager &)a_Mob).GetVilType()); break; } - case cMonster::mtZombie: + case mtZombie: { WriteByte(0x0c); WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); @@ -2880,14 +2880,14 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtGhast: + case mtGhast: { WriteByte(0x10); WriteByte(((const cGhast &)a_Mob).IsCharging()); break; } - case cMonster::mtWolf: + case mtWolf: { const cWolf & Wolf = (const cWolf &)a_Mob; Byte WolfStatus = 0; @@ -2915,7 +2915,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtSheep: + case mtSheep: { WriteByte(0x10); Byte SheepMetadata = 0; @@ -2928,7 +2928,7 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtEnderman: + case mtEnderman: { WriteByte(0x10); WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); @@ -2939,21 +2939,21 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtSkeleton: + case mtSkeleton: { WriteByte(0x0d); WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); break; } - case cMonster::mtWitch: + case mtWitch: { WriteByte(0x15); WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); break; } - case cMonster::mtWither: + case mtWither: { WriteByte(0x54); // Int at index 20 WriteInt(((const cWither &)a_Mob).GetWitherInvulnerableTicks()); @@ -2962,21 +2962,21 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } - case cMonster::mtSlime: + case mtSlime: { WriteByte(0x10); WriteByte(((const cSlime &)a_Mob).GetSize()); break; } - case cMonster::mtMagmaCube: + case mtMagmaCube: { WriteByte(0x10); WriteByte(((const cMagmaCube &)a_Mob).GetSize()); break; } - case cMonster::mtHorse: + case mtHorse: { const cHorse & Horse = (const cHorse &)a_Mob; int Flags = 0; diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 55cc014f3..df05a9fee 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1,6 +1,9 @@ #include "Globals.h" +#include "BlockEntities/ChestEntity.h" + +typedef cItemCallback cChestCallback; #include "IncrementalRedstoneSimulator.inc" @@ -13,7 +16,6 @@ #include "Blocks/BlockTripwireHook.h" #include "Blocks/BlockDoor.h" #include "Blocks/BlockPiston.h" -#include "BlockEntities/ChestEntity.h" cRedstoneSimulator * MakeIncrementalRedstoneSimulator(cWorld & a_World) { diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index e3c856328..eee2daa7c 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -6,6 +6,8 @@ #include "RedstoneSimulator.h" +typedef cItemCallback cEntityCallback; + @@ -1630,7 +1632,7 @@ void cIncrementalRedstoneSimulator +class cGetTrappedChestPlayers : + public cItemCallback +{ +public: + cGetTrappedChestPlayers(void) : + m_NumberOfPlayers(0) + { + } + virtual ~cGetTrappedChestPlayers() + { + } + virtual bool Item(ChestType * a_Chest) override + { + ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST); + m_NumberOfPlayers = a_Chest->GetNumberOfPlayers(); + return (m_NumberOfPlayers <= 0); + } -template class GetHandlerCompileTime, class ChestType> -void cIncrementalRedstoneSimulator::HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) -{ - class cGetTrappedChestPlayers : - public cChestCallback + unsigned char GetPowerLevel(void) const { - public: - cGetTrappedChestPlayers(void) : - m_NumberOfPlayers(0) - { - } + return std::min(m_NumberOfPlayers, MAX_POWER_LEVEL); + } - virtual bool Item(ChestType * a_Chest) override - { - ASSERT(a_Chest->GetBlockType() == E_BLOCK_TRAPPED_CHEST); - m_NumberOfPlayers = a_Chest->GetNumberOfPlayers(); - return (m_NumberOfPlayers <= 0); - } +private: + int m_NumberOfPlayers; - unsigned char GetPowerLevel(void) const - { - return std::min(m_NumberOfPlayers, MAX_POWER_LEVEL); - } +}; - private: - int m_NumberOfPlayers; - } GTCP; +template class GetHandlerCompileTime, class ChestType> +void cIncrementalRedstoneSimulator::HandleTrappedChest(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + cGetTrappedChestPlayers GTCP; int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index 1380f8841..e8887ce59 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -7,6 +7,7 @@ #include "../Defines.h" #include "../Entities/FallingBlock.h" #include "../Chunk.h" +#include "inifile/iniFile.h" diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index 7b944382b..d26702166 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -1,6 +1,11 @@ #include "Globals.h" +#include "../World.h" +#include "../BlockID.h" +#include "../Defines.h" +#include "../Chunk.h" + #include "Simulator.inc" #pragma clang diagnostic ignored "-Wweak-template-vtables" diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index ff53b17e1..7cc2f1344 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -2,7 +2,6 @@ #pragma once #include "../Vector3.h" -#include "inifile/iniFile.h" diff --git a/src/Simulator/Simulator.inc b/src/Simulator/Simulator.inc index 1599ea60f..511a6b4c2 100644 --- a/src/Simulator/Simulator.inc +++ b/src/Simulator/Simulator.inc @@ -1,10 +1,6 @@ #include "Simulator.h" -#include "../World.h" -#include "../BlockID.h" -#include "../Defines.h" -#include "../Chunk.h" diff --git a/src/World.cpp b/src/World.cpp index ded42f093..43f7faf94 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -791,8 +791,8 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile) AStringVector SplitList = StringSplitAndTrim(AllMonsters, ","); for (AStringVector::const_iterator itr = SplitList.begin(), end = SplitList.end(); itr != end; ++itr) { - cMonster::eType ToAdd = cMonster::StringToMobType(*itr); - if (ToAdd != cMonster::mtInvalidType) + eMonsterType ToAdd = cMonster::StringToMobType(*itr); + if (ToAdd != mtInvalidType) { m_AllowedMobs.insert(ToAdd); LOGD("Allowed mob: %s", itr->c_str()); @@ -3126,7 +3126,7 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ) -int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) +int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) { cMonster * Monster = NULL; diff --git a/src/World.h b/src/World.h index e4fe2965f..44bf13b03 100644 --- a/src/World.h +++ b/src/World.h @@ -768,7 +768,7 @@ public: bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ - virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) override; // tolua_export + virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) override; // tolua_export int SpawnMobFinalize(cMonster* a_Monster); /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise @@ -923,7 +923,7 @@ private: cChunkMap * m_ChunkMap; bool m_bAnimals; - std::set m_AllowedMobs; + std::set m_AllowedMobs; eWeather m_Weather; int m_WeatherInterval; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 68e541eba..92d754d3f 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -458,35 +458,35 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) const char * EntityClass = NULL; switch (a_Monster->GetMobType()) { - case cMonster::mtBat: EntityClass = "Bat"; break; - case cMonster::mtBlaze: EntityClass = "Blaze"; break; - case cMonster::mtCaveSpider: EntityClass = "CaveSpider"; break; - case cMonster::mtChicken: EntityClass = "Chicken"; break; - case cMonster::mtCow: EntityClass = "Cow"; break; - case cMonster::mtCreeper: EntityClass = "Creeper"; break; - case cMonster::mtEnderDragon: EntityClass = "EnderDragon"; break; - case cMonster::mtEnderman: EntityClass = "Enderman"; break; - case cMonster::mtGhast: EntityClass = "Ghast"; break; - case cMonster::mtGiant: EntityClass = "Giant"; break; - case cMonster::mtHorse: EntityClass = "Horse"; break; - case cMonster::mtIronGolem: EntityClass = "VillagerGolem"; break; - case cMonster::mtMagmaCube: EntityClass = "LavaSlime"; break; - case cMonster::mtMooshroom: EntityClass = "MushroomCow"; break; - case cMonster::mtOcelot: EntityClass = "Ozelot"; break; - case cMonster::mtPig: EntityClass = "Pig"; break; - case cMonster::mtSheep: EntityClass = "Sheep"; break; - case cMonster::mtSilverfish: EntityClass = "Silverfish"; break; - case cMonster::mtSkeleton: EntityClass = "Skeleton"; break; - case cMonster::mtSlime: EntityClass = "Slime"; break; - case cMonster::mtSnowGolem: EntityClass = "SnowMan"; break; - case cMonster::mtSpider: EntityClass = "Spider"; break; - case cMonster::mtSquid: EntityClass = "Squid"; break; - case cMonster::mtVillager: EntityClass = "Villager"; break; - case cMonster::mtWitch: EntityClass = "Witch"; break; - case cMonster::mtWither: EntityClass = "WitherBoss"; break; - case cMonster::mtWolf: EntityClass = "Wolf"; break; - case cMonster::mtZombie: EntityClass = "Zombie"; break; - case cMonster::mtZombiePigman: EntityClass = "PigZombie"; break; + case mtBat: EntityClass = "Bat"; break; + case mtBlaze: EntityClass = "Blaze"; break; + case mtCaveSpider: EntityClass = "CaveSpider"; break; + case mtChicken: EntityClass = "Chicken"; break; + case mtCow: EntityClass = "Cow"; break; + case mtCreeper: EntityClass = "Creeper"; break; + case mtEnderDragon: EntityClass = "EnderDragon"; break; + case mtEnderman: EntityClass = "Enderman"; break; + case mtGhast: EntityClass = "Ghast"; break; + case mtGiant: EntityClass = "Giant"; break; + case mtHorse: EntityClass = "Horse"; break; + case mtIronGolem: EntityClass = "VillagerGolem"; break; + case mtMagmaCube: EntityClass = "LavaSlime"; break; + case mtMooshroom: EntityClass = "MushroomCow"; break; + case mtOcelot: EntityClass = "Ozelot"; break; + case mtPig: EntityClass = "Pig"; break; + case mtSheep: EntityClass = "Sheep"; break; + case mtSilverfish: EntityClass = "Silverfish"; break; + case mtSkeleton: EntityClass = "Skeleton"; break; + case mtSlime: EntityClass = "Slime"; break; + case mtSnowGolem: EntityClass = "SnowMan"; break; + case mtSpider: EntityClass = "Spider"; break; + case mtSquid: EntityClass = "Squid"; break; + case mtVillager: EntityClass = "Villager"; break; + case mtWitch: EntityClass = "Witch"; break; + case mtWither: EntityClass = "WitherBoss"; break; + case mtWolf: EntityClass = "Wolf"; break; + case mtZombie: EntityClass = "Zombie"; break; + case mtZombiePigman: EntityClass = "PigZombie"; break; default: { ASSERT(!"Unhandled monster type"); @@ -506,24 +506,24 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddByte("CanPickUpLoot", (char)a_Monster->CanPickUpLoot()); switch (a_Monster->GetMobType()) { - case cMonster::mtBat: + case mtBat: { m_Writer.AddByte("BatFlags", ((const cBat *)a_Monster)->IsHanging()); break; } - case cMonster::mtCreeper: + case mtCreeper: { m_Writer.AddByte("powered", ((const cCreeper *)a_Monster)->IsCharged()); m_Writer.AddByte("ignited", ((const cCreeper *)a_Monster)->IsBlowing()); break; } - case cMonster::mtEnderman: + case mtEnderman: { m_Writer.AddShort("carried", (Int16)((const cEnderman *)a_Monster)->GetCarriedBlock()); m_Writer.AddShort("carriedData", (Int16)((const cEnderman *)a_Monster)->GetCarriedMeta()); break; } - case cMonster::mtHorse: + case mtHorse: { const cHorse & Horse = *((const cHorse *)a_Monster); m_Writer.AddByte("ChestedHorse", Horse.IsChested()); @@ -536,38 +536,38 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddByte("Saddle", Horse.IsSaddled()); break; } - case cMonster::mtMagmaCube: + case mtMagmaCube: { m_Writer.AddInt("Size", ((const cMagmaCube *)a_Monster)->GetSize()); break; } - case cMonster::mtSheep: + case mtSheep: { m_Writer.AddByte("Sheared", ((const cSheep *)a_Monster)->IsSheared()); m_Writer.AddByte("Color", ((const cSheep *)a_Monster)->GetFurColor()); break; } - case cMonster::mtSlime: + case mtSlime: { m_Writer.AddInt("Size", ((const cSlime *)a_Monster)->GetSize()); break; } - case cMonster::mtSkeleton: + case mtSkeleton: { m_Writer.AddByte("SkeletonType", (((const cSkeleton *)a_Monster)->IsWither() ? 1 : 0)); break; } - case cMonster::mtVillager: + case mtVillager: { m_Writer.AddInt("Profession", ((const cVillager *)a_Monster)->GetVilType()); break; } - case cMonster::mtWither: + case mtWither: { m_Writer.AddInt("Invul", ((const cWither *)a_Monster)->GetWitherInvulnerableTicks()); break; } - case cMonster::mtWolf: + case mtWolf: { const cWolf & Wolf = *((cWolf *)a_Monster); if (!Wolf.GetOwnerName().empty()) @@ -583,7 +583,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddInt("CollarColor", Wolf.GetCollarColor()); break; } - case cMonster::mtZombie: + case mtZombie: { m_Writer.AddByte("IsVillager", (((const cZombie *)a_Monster)->IsVillagerZombie() ? 1 : 0)); m_Writer.AddByte("IsBaby", (((const cZombie *)a_Monster)->IsBaby() ? 1 : 0)); -- cgit v1.2.3 From 16e9deba8d61abad80ef8a1935db1207fd6c3a68 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 20:55:46 +0200 Subject: Added an explicit setting for allowing BungeeCord handshake. --- src/Protocol/Protocol17x.cpp | 2 +- src/Server.cpp | 7 +++++++ src/Server.h | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 4f71b53b0..7d80e79fb 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -104,7 +104,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: // hostname\00ip-address\00uuid\00profile-properties-as-json AStringVector Params; - if (SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) + if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4)) { LOGD("Player at %s connected via BungeeCord", Params[1].c_str()); m_ServerAddress = Params[0]; diff --git a/src/Server.cpp b/src/Server.cpp index 069e2a169..969ffd693 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -259,6 +259,13 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) m_ServerID = sid.str(); m_ServerID.resize(16, '0'); } + + // Check if both BungeeCord and online mode are on, if so, warn the admin: + m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false); + if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate) + { + LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini."); + } m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false); m_ShouldLoadNamedPlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true); diff --git a/src/Server.h b/src/Server.h index f20e6932f..6d659fa40 100644 --- a/src/Server.h +++ b/src/Server.h @@ -131,6 +131,11 @@ public: // tolua_export Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */ bool ShouldLoadNamedPlayerData(void) const { return m_ShouldLoadNamedPlayerData; } + /** Returns true if BungeeCord logins (that specify the player's UUID) are allowed. + Read from settings, admins should set this to true only when they chain to BungeeCord, + it makes the server vulnerable to identity theft through direct connections. */ + bool ShouldAllowBungeeCord(void) const { return m_ShouldAllowBungeeCord; } + private: friend class cRoot; // so cRoot can create and destroy cServer @@ -230,6 +235,9 @@ private: This allows a seamless transition from name-based to UUID-based player storage. Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */ bool m_ShouldLoadNamedPlayerData; + + /** True if BungeeCord handshake packets (with player UUID) should be accepted. */ + bool m_ShouldAllowBungeeCord; cServer(void); -- cgit v1.2.3 From bf85c0b0abece030ba822223bd7b2dd6367e08eb Mon Sep 17 00:00:00 2001 From: nesco Date: Wed, 17 Sep 2014 21:17:06 +0200 Subject: Implementing Spectator Mode Adding some proprieties of the spectator game mode in player.cpp : - Players can't toss items - Players can't touch the ground --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 660ad3239..3920bdb56 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -451,7 +451,7 @@ void cPlayer::CancelChargingBow(void) void cPlayer::SetTouchGround(bool a_bTouchGround) { - if (IsGameModeSpectator()) // You can fly through the ground in survival + if (IsGameModeSpectator()) // You can fly through the ground in Spectator { return; } -- cgit v1.2.3 From 6f5aa487ed45f88f0fd0fc8bcd0d4af8d2d67888 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 23:24:22 +0200 Subject: Voronoi biomegen: Added JitterSize and OddRowOffset. --- src/Generating/BioGen.cpp | 148 ++++++++++++++++++++++++---------------------- src/VoronoiMap.cpp | 91 +++++++++++++++++++++++----- src/VoronoiMap.h | 13 +++- 3 files changed, 164 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 60ad4e3eb..217ca8f80 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -12,72 +12,6 @@ -//////////////////////////////////////////////////////////////////////////////// -// cBiomeGen: - -cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) -{ - AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); - if (BiomeGenName.empty()) - { - LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\"."); - BiomeGenName = "MultiStepMap"; - } - - cBiomeGen * res = NULL; - a_CacheOffByDefault = false; - if (NoCaseCompare(BiomeGenName, "constant") == 0) - { - res = new cBioGenConstant; - a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) - } - else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) - { - res = new cBioGenCheckerboard; - a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data - } - else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) - { - res = new cBioGenVoronoi(a_Seed); - } - else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0) - { - res = new cBioGenDistortedVoronoi(a_Seed); - } - else if (NoCaseCompare(BiomeGenName, "twolevel") == 0) - { - res = new cBioGenTwoLevel(a_Seed); - } - else - { - if (NoCaseCompare(BiomeGenName, "multistepmap") != 0) - { - LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str()); - } - res = new cBioGenMultiStepMap(a_Seed); - - /* - // Performance-testing: - LOGINFO("Measuring performance of cBioGenMultiStepMap..."); - clock_t BeginTick = clock(); - for (int x = 0; x < 5000; x++) - { - cChunkDef::BiomeMap Biomes; - res->GenBiomes(x * 5, x * 5, Biomes); - } - clock_t Duration = clock() - BeginTick; - LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); - //*/ - } - res->InitializeBiomeGen(a_IniFile); - - return res; -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cBioGenConstant: @@ -402,8 +336,13 @@ void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & void cBioGenVoronoi::InitializeBiomeGen(cIniFile & a_IniFile) { super::InitializeBiomeGen(a_IniFile); - m_Voronoi.SetCellSize(a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64)); - InitializeBiomes (a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", "")); + int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 128); + int JitterSize = a_IniFile.GetValueSetI("Generator", "VoronoiJitterSize", CellSize); + int OddRowOffset = a_IniFile.GetValueSetI("Generator", "VoronoiOddRowOffset", 0); + m_Voronoi.SetCellSize(CellSize); + m_Voronoi.SetJitterSize(JitterSize); + m_Voronoi.SetOddRowOffset(OddRowOffset); + InitializeBiomes(a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", "")); } @@ -846,9 +785,10 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap { for (int x = 0; x < cChunkDef::Width; x++) { - int MinDist1, MinDist2; - int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7; - int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11; + int SeedX, SeedZ, MinDist2; + int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7; + int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11; + int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ); cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1)); } } @@ -987,3 +927,69 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile) + +//////////////////////////////////////////////////////////////////////////////// +// cBiomeGen: + +cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) +{ + AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); + if (BiomeGenName.empty()) + { + LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\"."); + BiomeGenName = "MultiStepMap"; + } + + cBiomeGen * res = NULL; + a_CacheOffByDefault = false; + if (NoCaseCompare(BiomeGenName, "constant") == 0) + { + res = new cBioGenConstant; + a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) + } + else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) + { + res = new cBioGenCheckerboard; + a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data + } + else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) + { + res = new cBioGenVoronoi(a_Seed); + } + else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0) + { + res = new cBioGenDistortedVoronoi(a_Seed); + } + else if (NoCaseCompare(BiomeGenName, "twolevel") == 0) + { + res = new cBioGenTwoLevel(a_Seed); + } + else + { + if (NoCaseCompare(BiomeGenName, "multistepmap") != 0) + { + LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str()); + } + res = new cBioGenMultiStepMap(a_Seed); + + /* + // Performance-testing: + LOGINFO("Measuring performance of cBioGenMultiStepMap..."); + clock_t BeginTick = clock(); + for (int x = 0; x < 5000; x++) + { + cChunkDef::BiomeMap Biomes; + res->GenBiomes(x * 5, x * 5, Biomes); + } + clock_t Duration = clock() - BeginTick; + LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC); + //*/ + } + res->InitializeBiomeGen(a_IniFile); + + return res; +} + + + + diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp index 68147ebfc..5ad634fe4 100644 --- a/src/VoronoiMap.cpp +++ b/src/VoronoiMap.cpp @@ -59,8 +59,8 @@ void cVoronoiMap::SetOddRowOffset(int a_OddRowOffset) int cVoronoiMap::GetValueAt(int a_X, int a_Y) { - int MinDist1, MinDist2; - return GetValueAt(a_X, a_Y, MinDist1, MinDist2); + int SeedX, SeedY, MinDist2; + return GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2); } @@ -69,41 +69,47 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y) int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist) { - int MinDist2; - return GetValueAt(a_X, a_Y, a_MinDist, MinDist2); + int SeedX, SeedY, MinDist2; + int res = GetValueAt(a_X, a_Y, SeedX, SeedY, MinDist2); + a_MinDist = (a_X - SeedX) * (a_X - SeedX) + (a_Y - SeedY) * (a_Y - SeedY); + return res; } -int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2) +int cVoronoiMap::GetValueAt( + int a_X, int a_Y, // Coords to query + int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell + int & a_MinDist2 // Distance to the second closest cell +) { - // Note that due to historical reasons, the algorithm uses XZ coords, while the input uses XY coords. - // This is because the algorithm was first implemented directly in the biome generators which use MC coords. - int CellX = a_X / m_CellSize; - int CellZ = a_Y / m_CellSize; + int CellY = a_Y / m_CellSize; - UpdateCell(CellX, CellZ); + UpdateCell(CellX, CellY); // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell + int NearestSeedX = 0, NearestSeedY = 0; int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this int MinDist2 = MinDist; int res = 0; // Will be overriden for (int x = 0; x < 5; x++) { - for (int z = 0; z < 5; z++) + for (int y = 0; y < 5; y++) { - int SeedX = m_SeedX[x][z]; - int SeedZ = m_SeedZ[x][z]; + int SeedX = m_SeedX[x][y]; + int SeedY = m_SeedZ[x][y]; - int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y); + int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y); if (Dist < MinDist) { + NearestSeedX = SeedX; + NearestSeedY = SeedY; MinDist2 = MinDist; MinDist = Dist; - res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2); + res = m_Noise3.IntNoise2DInt(x + CellX - 2, y + CellY - 2); } else if (Dist < MinDist2) { @@ -112,7 +118,8 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2 } // for z } // for x - a_MinDist1 = MinDist; + a_NearestSeedX = NearestSeedX; + a_NearestSeedY = NearestSeedY; a_MinDist2 = MinDist2; return res; } @@ -121,6 +128,58 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2 +void cVoronoiMap::FindNearestSeeds( + int a_X, int a_Y, + int & a_NearestSeedX, int & a_NearestSeedY, + int & a_SecondNearestSeedX, int & a_SecondNearestSeedY +) +{ + int CellX = a_X / m_CellSize; + int CellY = a_Y / m_CellSize; + + UpdateCell(CellX, CellY); + + // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell + int NearestSeedX = 0, NearestSeedY = 0; + int SecondNearestSeedX = 0, SecondNearestSeedY = 0; + int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this + int MinDist2 = MinDist; + for (int x = 0; x < 5; x++) + { + for (int y = 0; y < 5; y++) + { + int SeedX = m_SeedX[x][y]; + int SeedY = m_SeedZ[x][y]; + + int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y); + if (Dist < MinDist) + { + SecondNearestSeedX = NearestSeedX; + SecondNearestSeedY = NearestSeedY; + MinDist2 = MinDist; + NearestSeedX = SeedX; + NearestSeedY = SeedY; + MinDist = Dist; + } + else if (Dist < MinDist2) + { + SecondNearestSeedX = SeedX; + SecondNearestSeedY = SeedY; + MinDist2 = Dist; + } + } // for z + } // for x + + a_NearestSeedX = NearestSeedX; + a_NearestSeedY = NearestSeedY; + a_SecondNearestSeedX = SecondNearestSeedX; + a_SecondNearestSeedY = SecondNearestSeedY; +} + + + + + void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ) { // If the specified cell is currently cached, bail out: diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h index 49f6c1da1..dfb11e9ce 100644 --- a/src/VoronoiMap.h +++ b/src/VoronoiMap.h @@ -40,7 +40,18 @@ public: /** Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache. */ - int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2); + int GetValueAt( + int a_X, int a_Y, // Coords to query + int & a_NearestSeedX, int & a_NearestSeedY, // Coords of the closest cell's seed + int & a_MinDist2 // Distance to the second closest cell's seed + ); + + /** Finds the nearest and second nearest seeds, returns their coords. */ + void FindNearestSeeds( + int a_X, int a_Y, + int & a_NearestSeedX, int & a_NearestSeedY, + int & a_SecondNearestSeedX, int & a_SecondNearestSeedY + ); protected: /// The noise used for generating Voronoi seeds -- cgit v1.2.3 From 95af3eb526dc8d3289d6b1ced6462283a6ebb6b3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 17 Sep 2014 23:32:14 +0200 Subject: Fixed minor style issues. --- src/Blocks/BlockHandler.cpp | 2 +- src/Entities/Player.cpp | 4 ++-- src/Root.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index cee2f4b99..30b303cfd 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -427,7 +427,7 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac if (a_CanDrop) { if ((a_Digger != NULL) && (a_Digger->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0)) - { + { switch (m_BlockType) { case E_BLOCK_CAKE: diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3920bdb56..38d42be14 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -451,7 +451,7 @@ void cPlayer::CancelChargingBow(void) void cPlayer::SetTouchGround(bool a_bTouchGround) { - if (IsGameModeSpectator()) // You can fly through the ground in Spectator + if (IsGameModeSpectator()) // You can fly through the ground in Spectator { return; } @@ -1514,7 +1514,7 @@ void cPlayer::TossPickup(const cItem & a_Item) void cPlayer::TossItems(const cItems & a_Items) { - if (IsGameModeSpectator()) // Players can't toss items in spectator + if (IsGameModeSpectator()) // Players can't toss items in spectator { return; } diff --git a/src/Root.cpp b/src/Root.cpp index 86a497a76..966a9b4ba 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -113,8 +113,8 @@ void cRoot::Start(void) LOG("--- Started Log ---\n"); #ifdef BUILD_ID - LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID ); - LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME ); + LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); + LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); #endif cDeadlockDetect dd; -- cgit v1.2.3 From be6d4a5912abcfe36a1f0fcee9d76e050a58c0ce Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 18 Sep 2014 16:04:03 +0200 Subject: 1.8: Simplified item metadata reading. --- src/ByteBuffer.cpp | 17 ----------------- src/ByteBuffer.h | 3 --- src/Protocol/Protocol18x.cpp | 10 +++------- 3 files changed, 3 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 262e0e3b5..17e8091c7 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -822,23 +822,6 @@ bool cByteBuffer::SkipRead(size_t a_Count) -bool cByteBuffer::ReverseRead(size_t a_Count) -{ - CHECK_THREAD; - CheckValid(); - if (m_ReadPos < a_Count) - { - return false; - } - - m_ReadPos -= a_Count; - return true; -} - - - - - void cByteBuffer::ReadAll(AString & a_Data) { CHECK_THREAD; diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index e200d2a7b..c1c71d8c4 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -107,9 +107,6 @@ public: /** Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer */ bool SkipRead(size_t a_Count); - - /** Reverse reading by a_Count bytes; returns false if not enough readed bytes in the ringbuffer */ - bool ReverseRead(size_t a_Count); /** Reads all available data into a_Data */ void ReadAll(AString & a_Data); diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 837c8ec99..a258d9585 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2497,17 +2497,13 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) a_Item.Empty(); } - HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, FirstChar); - if (FirstChar == 0) + AString Metadata; + a_ByteBuffer.ReadAll(Metadata); + if ((Metadata.size() == 0) || (Metadata[0] == 0)) { // No metadata return true; } - a_ByteBuffer.ReverseRead(1); - - // Read the metadata - AString Metadata; - a_ByteBuffer.ReadAll(Metadata); ParseItemMetadata(a_Item, Metadata); return true; -- cgit v1.2.3 From 43ed690520d3c3b47ed7ff6f48f868e8011565e0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 18 Sep 2014 18:50:17 +0200 Subject: Exported player list states to extra functions. --- src/ClientHandle.cpp | 48 ++++++++++-- src/ClientHandle.h | 138 +++++++++++++++++----------------- src/Entities/Player.cpp | 4 +- src/Protocol/Protocol.h | 144 ++++++++++++++++++------------------ src/Protocol/Protocol125.cpp | 71 ++++++++++++++---- src/Protocol/Protocol125.h | 144 ++++++++++++++++++------------------ src/Protocol/Protocol17x.cpp | 66 +++++++++++++++-- src/Protocol/Protocol17x.h | 144 ++++++++++++++++++------------------ src/Protocol/Protocol18x.cpp | 141 +++++++++++++++++++++-------------- src/Protocol/Protocol18x.h | 144 ++++++++++++++++++------------------ src/Protocol/ProtocolRecognizer.cpp | 44 ++++++++++- src/Protocol/ProtocolRecognizer.h | 144 ++++++++++++++++++------------------ src/World.cpp | 78 ++++++++++++++++++- src/World.h | 58 ++++++++------- 14 files changed, 837 insertions(+), 531 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index df6847767..487ef3867 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -127,7 +127,7 @@ cClientHandle::~cClientHandle() if (!m_Username.empty() && (World != NULL)) { // Send the Offline PlayerList packet: - World->BroadcastPlayerListItem(*m_Player, 4, this); + World->BroadcastPlayerListRemovePlayer(*m_Player, this); } if (World != NULL) { @@ -364,10 +364,10 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, m_Player->SendExperience(); // Send player list items - SendPlayerListItem(*m_Player, 0); - World->BroadcastPlayerListItem(*m_Player, 0); + SendPlayerListAddPlayer(*m_Player); + World->BroadcastPlayerListAddPlayer(*m_Player); World->SendPlayerList(m_Player); - + m_Player->Initialize(*World); m_State = csAuthenticated; @@ -2408,9 +2408,45 @@ void cClientHandle::SendPlayerAbilities() -void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, char a_Action) +void cClientHandle::SendPlayerListAddPlayer(const cPlayer & a_Player) +{ + m_Protocol->SendPlayerListAddPlayer(a_Player); +} + + + + + +void cClientHandle::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + m_Protocol->SendPlayerListRemovePlayer(a_Player); +} + + + + + +void cClientHandle::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + m_Protocol->SendPlayerListUpdateGameMode(a_Player); +} + + + + + +void cClientHandle::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + m_Protocol->SendPlayerListUpdatePing(a_Player); +} + + + + + +void cClientHandle::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) { - m_Protocol->SendPlayerListItem(a_Player, a_Action); + m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 27bfc756c..05d05e052 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -122,73 +122,77 @@ public: // The following functions send the various packets: // (Please keep these alpha-sorted) - void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle); - void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType); - void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage); - void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export - void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes); - void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = ""); - void SendChat (const cCompositeChat & a_Message); - void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer); - void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player); - void SendDestroyEntity (const cEntity & a_Entity); - void SendDisconnect (const AString & a_Reason); - void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); - void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration); - void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); - void SendEntityHeadLook (const cEntity & a_Entity); - void SendEntityLook (const cEntity & a_Entity); - void SendEntityMetadata (const cEntity & a_Entity); - void SendEntityProperties (const cEntity & a_Entity); - void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); - void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); - void SendEntityStatus (const cEntity & a_Entity, char a_Status); - void SendEntityVelocity (const cEntity & a_Entity); - void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion); - void SendGameMode (eGameMode a_GameMode); - void SendHealth (void); - void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item); - void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale); - void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale); - void SendMapInfo (int a_ID, unsigned int a_Scale); - void SendPaintingSpawn (const cPainting & a_Painting); - void SendPickupSpawn (const cPickup & a_Pickup); - void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export - void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); - void SendPlayerAbilities (void); - void SendPlayerListItem (const cPlayer & a_Player, char a_Action); - void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) - void SendPlayerMoveLook (void); - void SendPlayerPosition (void); - void SendPlayerSpawn (const cPlayer & a_Player); - void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp - void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); - void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false); - void SendExperience (void); - void SendExperienceOrb (const cExpOrb & a_ExpOrb); - void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); - void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); - void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); - void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export - void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); - void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); - void SendSpawnMob (const cMonster & a_Mob); - void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch); - void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0); - void SendStatistics (const cStatManager & a_Manager); - void SendTabCompletionResults(const AStringVector & a_Results); - void SendTeleportEntity (const cEntity & a_Entity); - void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); - void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export - void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); - void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); - void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); - void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ); - void SendWeather (eWeather a_Weather); - void SendWholeInventory (const cWindow & a_Window); - void SendWindowClose (const cWindow & a_Window); - void SendWindowOpen (const cWindow & a_Window); - void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value); + void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle); + void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType); + void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage); + void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export + void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes); + void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = ""); + void SendChat (const cCompositeChat & a_Message); + void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer); + void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player); + void SendDestroyEntity (const cEntity & a_Entity); + void SendDisconnect (const AString & a_Reason); + void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); + void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration); + void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); + void SendEntityHeadLook (const cEntity & a_Entity); + void SendEntityLook (const cEntity & a_Entity); + void SendEntityMetadata (const cEntity & a_Entity); + void SendEntityProperties (const cEntity & a_Entity); + void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); + void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); + void SendEntityStatus (const cEntity & a_Entity, char a_Status); + void SendEntityVelocity (const cEntity & a_Entity); + void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion); + void SendGameMode (eGameMode a_GameMode); + void SendHealth (void); + void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item); + void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale); + void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale); + void SendMapInfo (int a_ID, unsigned int a_Scale); + void SendPaintingSpawn (const cPainting & a_Painting); + void SendPickupSpawn (const cPickup & a_Pickup); + void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export + void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); + void SendPlayerAbilities (void); + void SendPlayerListAddPlayer (const cPlayer & a_Player); + void SendPlayerListRemovePlayer (const cPlayer & a_Player); + void SendPlayerListUpdateGameMode (const cPlayer & a_Player); + void SendPlayerListUpdatePing (const cPlayer & a_Player); + void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName); + void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) + void SendPlayerMoveLook (void); + void SendPlayerPosition (void); + void SendPlayerSpawn (const cPlayer & a_Player); + void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp + void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); + void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false); + void SendExperience (void); + void SendExperienceOrb (const cExpOrb & a_ExpOrb); + void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); + void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); + void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); + void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export + void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); + void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); + void SendSpawnMob (const cMonster & a_Mob); + void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch); + void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0); + void SendStatistics (const cStatManager & a_Manager); + void SendTabCompletionResults (const AStringVector & a_Results); + void SendTeleportEntity (const cEntity & a_Entity); + void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); + void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export + void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); + void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); + void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); + void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ); + void SendWeather (eWeather a_Weather); + void SendWholeInventory (const cWindow & a_Window); + void SendWindowClose (const cWindow & a_Window); + void SendWindowOpen (const cWindow & a_Window); + void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value); // tolua_begin const AString & GetUsername(void) const; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 826e0786f..36d8307b0 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -266,7 +266,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) cTimer t1; if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { - m_World->BroadcastPlayerListItem(*this, 2); + // m_World->BroadcastPlayerListUpdatePing(*this); m_LastPlayerListTime = t1.GetNowTime(); } @@ -1164,7 +1164,7 @@ void cPlayer::SetGameMode(eGameMode a_GameMode) SetCanFly(false); } - m_World->BroadcastPlayerListItem(*this, 1); + m_World->BroadcastPlayerListUpdateGameMode(*this); } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index eceec4974..f351ee4b9 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -57,76 +57,80 @@ public: virtual void DataReceived(const char * a_Data, size_t a_Size) = 0; // Sending stuff to clients (alphabetically sorted): - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) = 0; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0; - virtual void SendChat (const AString & a_Message) = 0; - virtual void SendChat (const cCompositeChat & a_Message) = 0; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0; - virtual void SendDestroyEntity (const cEntity & a_Entity) = 0; - virtual void SendDisconnect (const AString & a_Reason) = 0; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) = 0; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0; - virtual void SendEntityHeadLook (const cEntity & a_Entity) = 0; - virtual void SendEntityLook (const cEntity & a_Entity) = 0; - virtual void SendEntityMetadata (const cEntity & a_Entity) = 0; - virtual void SendEntityProperties (const cEntity & a_Entity) = 0; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) = 0; - virtual void SendEntityVelocity (const cEntity & a_Entity) = 0; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) = 0; - virtual void SendGameMode (eGameMode a_GameMode) = 0; - virtual void SendHealth (void) = 0; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) = 0; - virtual void SendKeepAlive (int a_PingID) = 0; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0; - virtual void SendLoginSuccess (void) = 0; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) = 0; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) = 0; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) = 0; - virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0; - virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0; - virtual void SendPlayerAbilities (void) = 0; - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; - virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; - virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) = 0; - virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) - virtual void SendPlayerMoveLook (void) = 0; - virtual void SendPlayerPosition (void) = 0; - virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) = 0; - virtual void SendExperience (void) = 0; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) = 0; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) = 0; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; - virtual void SendSpawnMob (const cMonster & a_Mob) = 0; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) = 0; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) = 0; - virtual void SendStatistics (const cStatManager & a_Manager) = 0; - virtual void SendTabCompletionResults(const AStringVector & a_Results) = 0; - virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; - virtual void SendWeather (eWeather a_Weather) = 0; - virtual void SendWholeInventory (const cWindow & a_Window) = 0; - virtual void SendWindowClose (const cWindow & a_Window) = 0; - virtual void SendWindowOpen (const cWindow & a_Window) = 0; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) = 0; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) = 0; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0; + virtual void SendChat (const AString & a_Message) = 0; + virtual void SendChat (const cCompositeChat & a_Message) = 0; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0; + virtual void SendDestroyEntity (const cEntity & a_Entity) = 0; + virtual void SendDisconnect (const AString & a_Reason) = 0; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) = 0; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0; + virtual void SendEntityHeadLook (const cEntity & a_Entity) = 0; + virtual void SendEntityLook (const cEntity & a_Entity) = 0; + virtual void SendEntityMetadata (const cEntity & a_Entity) = 0; + virtual void SendEntityProperties (const cEntity & a_Entity) = 0; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) = 0; + virtual void SendEntityVelocity (const cEntity & a_Entity) = 0; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) = 0; + virtual void SendGameMode (eGameMode a_GameMode) = 0; + virtual void SendHealth (void) = 0; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) = 0; + virtual void SendKeepAlive (int a_PingID) = 0; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0; + virtual void SendLoginSuccess (void) = 0; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) = 0; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) = 0; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) = 0; + virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0; + virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0; + virtual void SendPlayerAbilities (void) = 0; + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; + virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; + virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) = 0; + virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) = 0; + virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0; + virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) = 0; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) = 0; + virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) + virtual void SendPlayerMoveLook (void) = 0; + virtual void SendPlayerPosition (void) = 0; + virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) = 0; + virtual void SendExperience (void) = 0; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) = 0; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) = 0; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; + virtual void SendSpawnMob (const cMonster & a_Mob) = 0; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) = 0; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) = 0; + virtual void SendStatistics (const cStatManager & a_Manager) = 0; + virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; + virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + virtual void SendWeather (eWeather a_Weather) = 0; + virtual void SendWholeInventory (const cWindow & a_Window) = 0; + virtual void SendWindowClose (const cWindow & a_Window) = 0; + virtual void SendWindowOpen (const cWindow & a_Window) = 0; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) = 0; /// Returns the ServerID used for authentication through session.minecraft.net virtual AString GetAuthServerID(void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index c785553a5..4378ef466 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -719,28 +719,73 @@ void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, char a_Action) +void cProtocol125::SendPlayerListAddPlayer(const cPlayer & a_Player) { cCSLock Lock(m_CSPacket); - if (a_Action == 1) + WriteByte (PACKET_PLAYER_LIST_ITEM); + WriteString(a_Player.GetName()); + WriteBool (true); + WriteShort (a_Player.GetClientHandle()->GetPing()); + Flush(); +} + + + + + +void cProtocol125::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + cCSLock Lock(m_CSPacket); + WriteByte (PACKET_PLAYER_LIST_ITEM); + WriteString(a_Player.GetName()); + WriteBool (false); + WriteShort (0); + Flush(); +} + + + + + +void cProtocol125::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + // Not implemented in this protocol version + UNUSED(a_Player); +} + + + + + +void cProtocol125::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + // It is a simple add player packet in this protocol. + SendPlayerListAddPlayer(a_Player); +} + + + + + +void cProtocol125::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +{ + if (a_OldListName == a_Player.GetName()) { - // Ignore gamemode update return; } - AString PlayerName(a_Player.GetColor()); - PlayerName.append(a_Player.GetName()); - if (PlayerName.length() > 14) + cCSLock Lock(m_CSPacket); + + // Remove the old name from the tablist: { - PlayerName.erase(14); + WriteByte (PACKET_PLAYER_LIST_ITEM); + WriteString(a_OldListName); + WriteBool (false); + WriteShort (0); + Flush(); } - PlayerName += cChatColor::White; - WriteByte ((unsigned char)PACKET_PLAYER_LIST_ITEM); - WriteString(PlayerName); - WriteBool (a_Action != 4); - WriteShort ((a_Action == 4) ? 0 : a_Player.GetClientHandle()->GetPing()); - Flush(); + SendPlayerListAddPlayer(a_Player); } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 4e140331a..4241c1fd4 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -28,76 +28,80 @@ public: virtual void DataReceived(const char * a_Data, size_t a_Size) override; /// Sending stuff to clients (alphabetically sorted): - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendDisconnect (const AString & a_Reason) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendEntityHeadLook (const cEntity & a_Entity) override; - virtual void SendEntityLook (const cEntity & a_Entity) override; - virtual void SendEntityMetadata (const cEntity & a_Entity) override; - virtual void SendEntityProperties (const cEntity & a_Entity) override; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; - virtual void SendKeepAlive (int a_PingID) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendPlayerPosition (void) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override {} // This protocol doesn't support such message - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override {} // This protocol doesn't support such message - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; - virtual void SendTabCompletionResults(const AStringVector & a_Results) override; - virtual void SendTeleportEntity (const cEntity & a_Entity) override; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {} - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - virtual void SendWindowClose (const cWindow & a_Window) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendChat (const cCompositeChat & a_Message) override; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; + virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendEntityHeadLook (const cEntity & a_Entity) override; + virtual void SendEntityLook (const cEntity & a_Entity) override; + virtual void SendEntityMetadata (const cEntity & a_Entity) override; + virtual void SendEntityProperties (const cEntity & a_Entity) override; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendKeepAlive (int a_PingID) override; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendLoginSuccess (void) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; + virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerMaxSpeed (void) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendPlayerPosition (void) override; + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override {} // This protocol doesn't support such message + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override {} // This protocol doesn't support such message + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnMob (const cMonster & a_Mob) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; + virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendTabCompletionResults (const AStringVector & a_Results) override; + virtual void SendTeleportEntity (const cEntity & a_Entity) override; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {} + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendWeather (eWeather a_Weather) override; + virtual void SendWholeInventory (const cWindow & a_Window) override; + virtual void SendWindowClose (const cWindow & a_Window) override; + virtual void SendWindowOpen (const cWindow & a_Window) override; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; virtual AString GetAuthServerID(void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index f51f15ec2..05935fbe1 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -777,19 +777,71 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, char a_Action) +void cProtocol172::SendPlayerListAddPlayer(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - if (a_Action == 1) + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteBool(true); + Pkt.WriteShort(a_Player.GetClientHandle()->GetPing()); +} + + + + + +void cProtocol172::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x38); + Pkt.WriteString(a_Player.GetName()); + Pkt.WriteBool(false); + Pkt.WriteShort(0); +} + + + + + +void cProtocol172::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + // Not implemented in this protocol version + UNUSED(a_Player); +} + + + + + +void cProtocol172::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + // It is a simple add player packet in this protocol. + SendPlayerListAddPlayer(a_Player); +} + + + + + +void cProtocol172::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +{ + ASSERT(m_State == 3); // In game mode? + if (a_OldListName == a_Player.GetName()) { - // Ignore gamemode update return; } - cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteString(a_Player.GetName()); - Pkt.WriteBool(a_Action != 4); - Pkt.WriteShort((a_Action == 4) ? 0 : a_Player.GetClientHandle()->GetPing()); + // Remove the old name from the tablist: + { + cPacketizer Pkt(*this, 0x38); + Pkt.WriteString(a_OldListName); + Pkt.WriteBool(false); + Pkt.WriteShort(0); + } + + SendPlayerListAddPlayer(a_Player); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 6668d0a87..7ec7d0fce 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -61,76 +61,80 @@ public: virtual void DataReceived(const char * a_Data, size_t a_Size) override; /** Sending stuff to clients (alphabetically sorted): */ - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendDisconnect (const AString & a_Reason) override; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendEntityHeadLook (const cEntity & a_Entity) override; - virtual void SendEntityLook (const cEntity & a_Entity) override; - virtual void SendEntityMetadata (const cEntity & a_Entity) override; - virtual void SendEntityProperties (const cEntity & a_Entity) override; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; - virtual void SendKeepAlive (int a_PingID) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendPlayerAbilities (void) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendPlayerPosition (void) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; - virtual void SendTabCompletionResults(const AStringVector & a_Results) override; - virtual void SendTeleportEntity (const cEntity & a_Entity) override; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - virtual void SendWindowClose (const cWindow & a_Window) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendChat (const cCompositeChat & a_Message) override; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; + virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendEntityHeadLook (const cEntity & a_Entity) override; + virtual void SendEntityLook (const cEntity & a_Entity) override; + virtual void SendEntityMetadata (const cEntity & a_Entity) override; + virtual void SendEntityProperties (const cEntity & a_Entity) override; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendKeepAlive (int a_PingID) override; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendLoginSuccess (void) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendPlayerAbilities (void) override; + virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerMaxSpeed (void) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendPlayerPosition (void) override; + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnMob (const cMonster & a_Mob) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; + virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendTabCompletionResults (const AStringVector & a_Results) override; + virtual void SendTeleportEntity (const cEntity & a_Entity) override; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendWeather (eWeather a_Weather) override; + virtual void SendWholeInventory (const cWindow & a_Window) override; + virtual void SendWindowClose (const cWindow & a_Window) override; + virtual void SendWindowOpen (const cWindow & a_Window) override; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; virtual AString GetAuthServerID(void) override { return m_AuthServerID; } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index a258d9585..293080166 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -793,74 +793,107 @@ void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol180::SendPlayerListItem(const cPlayer & a_Player, char a_Action) +void cProtocol180::SendPlayerListAddPlayer(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteVarInt(a_Action); + Pkt.WriteVarInt(0); Pkt.WriteVarInt(1); Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteString(a_Player.GetName()); - switch (a_Action) + const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); + Pkt.WriteVarInt(Properties.size()); + for (Json::Value::iterator itr = Properties.begin(), end = Properties.end(); itr != end; ++itr) { - case 0: - { - // Add Player - Pkt.WriteString(a_Player.GetName()); - - const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); - Pkt.WriteVarInt(Properties.size()); - for (Json::Value::iterator itr = Properties.begin(), end = Properties.end(); itr != end; ++itr) - { - Pkt.WriteString(((Json::Value)*itr).get("name", "").asString()); - Pkt.WriteString(((Json::Value)*itr).get("value", "").asString()); - AString Signature = ((Json::Value)*itr).get("signature", "").asString(); - if (Signature.empty()) - { - Pkt.WriteBool(false); - } - else - { - Pkt.WriteBool(true); - Pkt.WriteString(Signature); - } - } - - Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); - Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); - Pkt.WriteBool(false); - break; - } - case 1: - { - // Update GameMode - Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); - break; - } - case 2: - { - // Update Ping - Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); - break; - } - case 3: + Pkt.WriteString(((Json::Value)*itr).get("name", "").asString()); + Pkt.WriteString(((Json::Value)*itr).get("value", "").asString()); + AString Signature = ((Json::Value)*itr).get("signature", "").asString(); + if (Signature.empty()) { - // Update DisplayName Pkt.WriteBool(false); - break; } - case 4: + else { - // Remove player - break; - } - default: - { - ASSERT(!"Unhandled player list item action!"); - return; + Pkt.WriteBool(true); + Pkt.WriteString(Signature); } } + + Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); + Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); + Pkt.WriteBool(false); +} + + + + + +void cProtocol180::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt(4); + Pkt.WriteVarInt(1); + Pkt.WriteUUID(a_Player.GetUUID()); +} + + + + + +void cProtocol180::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt(1); + Pkt.WriteVarInt(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); +} + + + + + +void cProtocol180::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt(2); + Pkt.WriteVarInt(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); +} + + + + + +void cProtocol180::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +{ + UNUSED(a_OldListName); + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, 0x38); // Playerlist Item packet + Pkt.WriteVarInt(3); + Pkt.WriteVarInt(1); + Pkt.WriteUUID(a_Player.GetUUID()); + + // TODO: Replace this with GetPlayerListName() (It's already done in other pull request) + if (a_Player.GetName().empty()) + { + Pkt.WriteBool(false); + } + else + { + Pkt.WriteBool(true); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_Player.GetName().c_str())); + } } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 7ba2b92cd..fd3121d7f 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -60,76 +60,80 @@ public: virtual void DataReceived(const char * a_Data, size_t a_Size) override; /** Sending stuff to clients (alphabetically sorted): */ - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendDisconnect (const AString & a_Reason) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendEntityHeadLook (const cEntity & a_Entity) override; - virtual void SendEntityLook (const cEntity & a_Entity) override; - virtual void SendEntityMetadata (const cEntity & a_Entity) override; - virtual void SendEntityProperties (const cEntity & a_Entity) override; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; - virtual void SendKeepAlive (int a_PingID) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendPlayerAbilities (void) override; - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendPlayerPosition (void) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; - virtual void SendTabCompletionResults(const AStringVector & a_Results) override; - virtual void SendTeleportEntity (const cEntity & a_Entity) override; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - virtual void SendWindowClose (const cWindow & a_Window) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendChat (const cCompositeChat & a_Message) override; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; + virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendEntityHeadLook (const cEntity & a_Entity) override; + virtual void SendEntityLook (const cEntity & a_Entity) override; + virtual void SendEntityMetadata (const cEntity & a_Entity) override; + virtual void SendEntityProperties (const cEntity & a_Entity) override; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendKeepAlive (int a_PingID) override; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendLoginSuccess (void) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendPlayerAbilities (void) override; + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerMaxSpeed (void) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendPlayerPosition (void) override; + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnMob (const cMonster & a_Mob) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; + virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendTabCompletionResults (const AStringVector & a_Results) override; + virtual void SendTeleportEntity (const cEntity & a_Entity) override; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendWeather (eWeather a_Weather) override; + virtual void SendWholeInventory (const cWindow & a_Window) override; + virtual void SendWindowClose (const cWindow & a_Window) override; + virtual void SendWindowOpen (const cWindow & a_Window) override; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; virtual AString GetAuthServerID(void) override { return m_AuthServerID; } diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 611ef6ce0..36e791fc7 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -489,10 +489,50 @@ void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_A -void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, char a_Action) +void cProtocolRecognizer::SendPlayerListAddPlayer(const cPlayer & a_Player) { ASSERT(m_Protocol != NULL); - m_Protocol->SendPlayerListItem(a_Player, a_Action); + m_Protocol->SendPlayerListAddPlayer(a_Player); +} + + + + + +void cProtocolRecognizer::SendPlayerListRemovePlayer(const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerListRemovePlayer(a_Player); +} + + + + + +void cProtocolRecognizer::SendPlayerListUpdateGameMode(const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerListUpdateGameMode(a_Player); +} + + + + + +void cProtocolRecognizer::SendPlayerListUpdatePing(const cPlayer & a_Player) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerListUpdatePing(a_Player); +} + + + + + +void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 9a0169b97..3177f06ae 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -64,76 +64,80 @@ public: virtual void DataReceived(const char * a_Data, size_t a_Size) override; /// Sending stuff to clients (alphabetically sorted): - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendDisconnect (const AString & a_Reason) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendEntityHeadLook (const cEntity & a_Entity) override; - virtual void SendEntityLook (const cEntity & a_Entity) override; - virtual void SendEntityMetadata (const cEntity & a_Entity) override; - virtual void SendEntityProperties (const cEntity & a_Entity) override; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; - virtual void SendKeepAlive (int a_PingID) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendPlayerAbilities (void) override; - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, char a_Action) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendPlayerPosition (void) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; - virtual void SendTabCompletionResults(const AStringVector & a_Results) override; - virtual void SendTeleportEntity (const cEntity & a_Entity) override; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - virtual void SendWindowClose (const cWindow & a_Window) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendChat (const cCompositeChat & a_Message) override; + virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; + virtual void SendDestroyEntity (const cEntity & a_Entity) override; + virtual void SendDisconnect (const AString & a_Reason) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; + virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; + virtual void SendEntityHeadLook (const cEntity & a_Entity) override; + virtual void SendEntityLook (const cEntity & a_Entity) override; + virtual void SendEntityMetadata (const cEntity & a_Entity) override; + virtual void SendEntityProperties (const cEntity & a_Entity) override; + virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; + virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; + virtual void SendEntityVelocity (const cEntity & a_Entity) override; + virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; + virtual void SendKeepAlive (int a_PingID) override; + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendLoginSuccess (void) override; + virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; + virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; + virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendPlayerAbilities (void) override; + virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; + virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerMaxSpeed (void) override; + virtual void SendPlayerMoveLook (void) override; + virtual void SendPlayerPosition (void) override; + virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; + virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; + virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; + virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; + virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; + virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; + virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnMob (const cMonster & a_Mob) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; + virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; + virtual void SendStatistics (const cStatManager & a_Manager) override; + virtual void SendTabCompletionResults (const AStringVector & a_Results) override; + virtual void SendTeleportEntity (const cEntity & a_Entity) override; + virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; + virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual void SendWeather (eWeather a_Weather) override; + virtual void SendWholeInventory (const cWindow & a_Window) override; + virtual void SendWindowClose (const cWindow & a_Window) override; + virtual void SendWindowOpen (const cWindow & a_Window) override; + virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; virtual AString GetAuthServerID(void) override; diff --git a/src/World.cpp b/src/World.cpp index 2d2137b3f..71ce7e680 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2153,7 +2153,7 @@ void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src -void cWorld::BroadcastPlayerListItem(const cPlayer & a_Player, char a_Action, const cClientHandle * a_Exclude) +void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2163,7 +2163,79 @@ void cWorld::BroadcastPlayerListItem(const cPlayer & a_Player, char a_Action, co { continue; } - ch->SendPlayerListItem(a_Player, a_Action); + ch->SendPlayerListAddPlayer(a_Player); + } +} + + + + + +void cWorld::BroadcastPlayerListRemovePlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + ch->SendPlayerListRemovePlayer(a_Player); + } +} + + + + + +void cWorld::BroadcastPlayerListUpdateGameMode(const cPlayer & a_Player, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + ch->SendPlayerListUpdateGameMode(a_Player); + } +} + + + + + +void cWorld::BroadcastPlayerListUpdatePing(const cPlayer & a_Player, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + ch->SendPlayerListUpdatePing(a_Player); + } +} + + + + + +void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + ch->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); } } @@ -2686,7 +2758,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) cClientHandle * ch = (*itr)->GetClientHandle(); if ((ch != NULL) && !ch->IsDestroyed()) { - a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), 0); + a_DestPlayer->GetClientHandle()->SendPlayerListAddPlayer(*(*itr)); } } } diff --git a/src/World.h b/src/World.h index c7b377a21..391124a03 100644 --- a/src/World.h +++ b/src/World.h @@ -223,33 +223,37 @@ public: void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_end - void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListItem (const cPlayer & a_Player, char a_Action, const cClientHandle * a_Exclude = NULL); - void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); - void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); - void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); - void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); - void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); - void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); - virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); + void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); + void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + virtual void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName, const cClientHandle * a_Exclude = NULL); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); + void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); + void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); + void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); + void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); + void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); virtual cBroadcastInterface & GetBroadcastManager(void) override { -- cgit v1.2.3 From 52c875531ec3622eedd7096e44f6bc67c5e5483b Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 18 Sep 2014 18:51:36 +0200 Subject: Derp --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 36d8307b0..55065d550 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -266,7 +266,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) cTimer t1; if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { - // m_World->BroadcastPlayerListUpdatePing(*this); + m_World->BroadcastPlayerListUpdatePing(*this); m_LastPlayerListTime = t1.GetNowTime(); } -- cgit v1.2.3 From 6aa331a4fa314daebfb76161b7e26685d7786e2e Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 19 Sep 2014 15:07:01 +0200 Subject: Code improvements. --- src/Protocol/ChunkDataSerializer.cpp | 62 +++++++++++++++++------------------- src/Protocol/ChunkDataSerializer.h | 2 +- src/Protocol/Protocol18x.cpp | 8 ++--- src/Protocol/ProtocolRecognizer.cpp | 2 +- 4 files changed, 36 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 61df24c31..a133cc0e3 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -45,7 +45,7 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int { case RELEASE_1_2_5: Serialize29(data); break; case RELEASE_1_3_2: Serialize39(data); break; - case RELEASE_1_8_0: Serialize80(data, a_ChunkX, a_ChunkZ); break; + case RELEASE_1_8_0: Serialize47(data, a_ChunkX, a_ChunkZ); break; // TODO: Other protocol versions may serialize the data differently; implement here default: @@ -181,43 +181,41 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) -void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_ChunkZ) +void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_ChunkZ) { - // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream) - - // Blocktypes converter (1.8 included the meta into the blocktype): - unsigned char Blocks[cChunkDef::NumBlocks * 2]; - size_t LastOffset = 0; - for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++) - { - BLOCKTYPE BlockType = m_BlockTypes[Index] & 0xFF; - NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; - Blocks[LastOffset] = (unsigned char)(BlockType << 4) | BlockMeta; - Blocks[LastOffset + 1] = (unsigned char)(BlockType >> 4); - LastOffset += 2; - } - - const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; - const int BlockLightOffset = sizeof(Blocks); - const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight); - const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight); - const int DataSize = BiomeOffset + BiomeDataSize; - - // Temporary buffer for the composed data: - char AllData [DataSize]; - memcpy(AllData, Blocks, sizeof(Blocks)); - memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight)); - memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight)); - memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize); + // This function returns the fully compressed packet (including packet size), not the raw packet! + // Create the packet: cByteBuffer Packet(512 KiB); Packet.WriteVarInt(0x21); // Packet id (Chunk Data packet) Packet.WriteBEInt(a_ChunkX); Packet.WriteBEInt(a_ChunkZ); Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag Packet.WriteBEShort((short) 0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff - Packet.WriteVarInt(DataSize); // Chunk size - Packet.WriteBuf(AllData, DataSize); // Chunk data + + // Write the chunk size: + const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; + UInt32 ChunkSize = ( + (cChunkDef::NumBlocks * 2) + // Block meta + type + sizeof(m_BlockLight) + // Block light + sizeof(m_BlockSkyLight) + // Block sky light + BiomeDataSize // Biome data + ); + Packet.WriteVarInt(ChunkSize); + + // Write the block types to the packet: + for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++) + { + BLOCKTYPE BlockType = m_BlockTypes[Index] & 0xFF; + NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f; + Packet.WriteByte((unsigned char)(BlockType << 4) | BlockMeta); + Packet.WriteByte((unsigned char)(BlockType >> 4)); + } + + // Write the rest: + Packet.WriteBuf(m_BlockLight, sizeof(m_BlockLight)); + Packet.WriteBuf(m_BlockSkyLight, sizeof(m_BlockSkyLight)); + Packet.WriteBuf(m_BiomeData, BiomeDataSize); AString PacketData; Packet.ReadAll(PacketData); @@ -236,13 +234,13 @@ void cChunkDataSerializer::Serialize80(AString & a_Data, int a_ChunkX, int a_Chu else { AString PostData; - Buffer.WriteVarInt(Packet.GetUsedSpace() + 1); + Buffer.WriteVarInt((UInt32)Packet.GetUsedSpace() + 1); Buffer.WriteVarInt(0); Buffer.ReadAll(PostData); Buffer.CommitRead(); a_Data.clear(); - a_Data.resize(PostData.size() + PacketData.size()); + a_Data.reserve(PostData.size() + PacketData.size()); a_Data.append(PostData.data(), PostData.size()); a_Data.append(PacketData.data(), PacketData.size()); } diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index 3caa89d41..a082ef3d8 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -24,7 +24,7 @@ protected: void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5 void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10 - void Serialize80(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8 + void Serialize47(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8 public: enum diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 293080166..4b78bc4cd 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -75,6 +75,7 @@ Implements the 1.8.x protocol classes: const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... +const uLongf MAX_COMPRESSED_PACKET_LEN = 200 KiB; // Maximum size of compressed packets. @@ -1513,11 +1514,10 @@ void cProtocol180::SendWindowProperty(const cWindow & a_Window, int a_Property, bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_CompressedData) { // Compress the data: - const uLongf CompressedMaxSize = 200000; - char CompressedData[CompressedMaxSize]; + char CompressedData[MAX_COMPRESSED_PACKET_LEN]; uLongf CompressedSize = compressBound(a_Packet.size()); - if (CompressedSize >= CompressedMaxSize) + if (CompressedSize >= MAX_COMPRESSED_PACKET_LEN) { ASSERT(!"Too high packet size."); return false; @@ -1541,7 +1541,7 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress Buffer.CommitRead(); a_CompressedData.clear(); - a_CompressedData.resize(LengthData.size() + CompressedSize); + a_CompressedData.reserve(LengthData.size() + CompressedSize); a_CompressedData.append(LengthData.data(), LengthData.size()); a_CompressedData.append(CompressedData, CompressedSize); return true; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 4516975bf..a5b745c2f 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -955,7 +955,7 @@ bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void) m_Protocol = new cProtocol132(m_Client); return true; } - //case PROTO_VERSION_1_4_2: + case PROTO_VERSION_1_4_2: case PROTO_VERSION_1_4_4: { m_Protocol = new cProtocol142(m_Client); -- cgit v1.2.3 From 3676a84916103ff1fcab472217817e64f5e341a5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 20 Sep 2014 23:01:42 +0200 Subject: Fixed cParsedNBT::FindTagByPath(). There was an off-by-one error in the name handling. --- src/WorldStorage/FastNBT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index c6294b99c..ed8e8bb14 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -310,7 +310,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const { continue; } - Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1); + Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin); if (Tag < 0) { return -1; -- cgit v1.2.3 From cb709250779ee6e29d29cacff84e3980983dbd77 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 21 Sep 2014 19:24:45 +0100 Subject: Fix crash in cLineBlockTracer * Fixes #1418 --- src/LineBlockTracer.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index f03e796d1..71b8334fa 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -227,9 +227,11 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) } // Update the current chunk - if (a_Chunk != NULL) + a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); + if (a_Chunk == NULL) { - a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); + m_Callbacks->OnNoChunk(); + return false; } if (a_Chunk->IsValid()) @@ -245,13 +247,10 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) return false; } } - else + else if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ, m_CurrentFace)) { - if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ, m_CurrentFace)) - { - // The callback terminated the trace - return false; - } + // The callback terminated the trace + return false; } } } -- cgit v1.2.3 From 195b646aa4189ec9858f4994754eadd2c05ef9df Mon Sep 17 00:00:00 2001 From: Chris Darnell Date: Mon, 22 Sep 2014 03:22:36 -0400 Subject: Made it compile with clang --- src/Entities/Entity.cpp | 4 ++-- src/Entities/Minecart.cpp | 4 ++-- src/Generating/Caves.cpp | 2 +- src/Generating/Noise3DGenerator.cpp | 4 ++-- src/LineBlockTracer.cpp | 6 +++--- src/Tracer.cpp | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 42b207c48..996f2fff3 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -260,7 +260,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R void cEntity::SetYawFromSpeed(void) { const double EPS = 0.0000001; - if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS)) + if ((std::abs(m_Speed.x) < EPS) && (std::abs(m_Speed.z) < EPS)) { // atan2() may overflow or is undefined, pick any number SetYaw(0); @@ -277,7 +277,7 @@ void cEntity::SetPitchFromSpeed(void) { const double EPS = 0.0000001; double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component - if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS)) + if ((std::abs(xz) < EPS) && (std::abs(m_Speed.y) < EPS)) { // atan2() may overflow or is undefined, pick any number SetPitch(0); diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 1501eea84..bc9e21d8e 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -876,7 +876,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - if (abs(Distance.z) < 0.001) + if (std::abs(Distance.z) < 0.001) { Distance.z = 0.001; } @@ -925,7 +925,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - if (abs(Distance.z) < 0.001) + if (std::abs(Distance.z) < 0.001) { Distance.z = 0.001; } diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 71154dff9..fc925a150 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -755,7 +755,7 @@ void cStructGenDualRidgeCaves::GenFinish(cChunkDesc & a_ChunkDesc) float n2 = m_Noise2.CubicNoise3D(xx, yy, zz); float n3 = m_Noise1.CubicNoise3D(xx * 4, yy * 4, zz * 4) / 4; float n4 = m_Noise2.CubicNoise3D(xx * 4, yy * 4, zz * 4) / 4; - if ((abs(n1 + n3) * abs(n2 + n4)) > m_Threshold) + if ((std::abs(n1 + n3) * std::abs(n2 + n4)) > m_Threshold) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR); } diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index eb816f564..c3ca30384 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -236,7 +236,7 @@ void cNoise3DGenerator::GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DAT m_Cubic.Generate2D(Height, DIM_X, DIM_Z, StartX / 25, EndX / 25, StartZ / 25, EndZ / 25); for (size_t i = 0; i < ARRAYCOUNT(Height); i++) { - Height[i] = abs(Height[i]) * m_HeightAmplification + 1; + Height[i] = std::abs(Height[i]) * m_HeightAmplification + 1; } // Modify the noise by height data: @@ -395,7 +395,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) for (int x = 0; x < 17; x += UPSCALE_X) { NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + x)) / m_FrequencyX; - NOISE_DATATYPE val = abs(m_Noise1.CubicNoise2D(NoiseX / 5, NoiseZ / 5)) * m_HeightAmplification + 1; + NOISE_DATATYPE val = std::abs(m_Noise1.CubicNoise2D(NoiseX / 5, NoiseZ / 5)) * m_HeightAmplification + 1; Height[x + 17 * z] = val * val * val; } } diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index 71b8334fa..1b42081c2 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -146,7 +146,7 @@ bool cLineBlockTracer::MoveToNextBlock(void) dirY, dirZ, } Direction = dirNONE; - if (abs(m_DiffX) > EPS) + if (std::abs(m_DiffX) > EPS) { double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; Coeff = (DestX - m_StartX) / m_DiffX; @@ -155,7 +155,7 @@ bool cLineBlockTracer::MoveToNextBlock(void) Direction = dirX; } } - if (abs(m_DiffY) > EPS) + if (std::abs(m_DiffY) > EPS) { double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY; double CoeffY = (DestY - m_StartY) / m_DiffY; @@ -165,7 +165,7 @@ bool cLineBlockTracer::MoveToNextBlock(void) Direction = dirY; } } - if (abs(m_DiffZ) > EPS) + if (std::abs(m_DiffZ) > EPS) { double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ; double CoeffZ = (DestZ - m_StartZ) / m_DiffZ; diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 756147a7b..8ccd18071 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -250,7 +250,7 @@ int LinesCross(float x0, float y0, float x1, float y1, float x2, float y2, float // float linx, liny; float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2); - if (abs(d)<0.001) {return 0;} + if (std::abs(d)<0.001) {return 0;} float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d; if (AB>=0.0 && AB<=1.0) { -- cgit v1.2.3 From bcb11078e323240b21d5ff1de8b694212eea2bbf Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 22 Sep 2014 17:15:08 +0200 Subject: Fixed item nbt reading. --- src/Protocol/Protocol18x.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++- src/Protocol/Protocol18x.h | 3 + 2 files changed, 168 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 4b78bc4cd..07e21923c 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1652,6 +1652,169 @@ void cProtocol180::FixItemFramePositions(int a_ObjectData, double & a_PosX, doub +AString cProtocol180::ReadNBTDataFromBuffer(cByteBuffer & a_ByteBuffer, int a_ListTag) +{ + cByteBuffer BufferCache(64 KiB); + AString Data; + + while (a_ByteBuffer.GetReadableSpace() != 0) + { + unsigned char TypeID; + if (a_ListTag != 0) + { + TypeID = (unsigned char)a_ListTag; + } + else + { + if (!a_ByteBuffer.ReadByte(TypeID)) + { + // Can't read the next byte + break; + } + BufferCache.WriteByte(TypeID); + } + + if ((TypeID <= eTagType::TAG_Min) || (TypeID > eTagType::TAG_Max)) + { + // Bad type id (or TAG_End) + break; + } + eTagType TagType = static_cast(TypeID); + + // Read the following string length: + if (a_ListTag == 0) + { + short StrLength = 0; + if (!a_ByteBuffer.ReadBEShort(StrLength)) + { + // Can't read string length + return Data; + } + BufferCache.WriteBEShort(StrLength); + + // Read string and write to BufferCache: + AString TagTitle; + if (!a_ByteBuffer.ReadString(TagTitle, (size_t)StrLength)) + { + // Can't read string + return Data; + } + BufferCache.WriteBuf(TagTitle.data(), TagTitle.size()); + } + + size_t TagLength = 0; + switch (TagType) + { + case eTagType::TAG_Byte: TagLength = sizeof(Byte); break; + case eTagType::TAG_Short: TagLength = sizeof(short); break; + case eTagType::TAG_Int: TagLength = sizeof(int); break; + case eTagType::TAG_Long: TagLength = sizeof(long); break; + case eTagType::TAG_Float: TagLength = sizeof(float); break; + case eTagType::TAG_Double: TagLength = sizeof(double); break; + case eTagType::TAG_End: break; + case eTagType::TAG_Compound: + { + AString CompoundData = ReadNBTDataFromBuffer(a_ByteBuffer); + Data.append(CompoundData.data(), CompoundData.size()); + break; + } + case eTagType::TAG_List: + { + Byte ListType; + int ListLength; + if (!a_ByteBuffer.ReadByte(ListType) || !a_ByteBuffer.ReadBEInt(ListLength) || (ListLength < 0)) + { + // Bad list type or list length + return Data; + } + LOGWARNING("LIST, Type: %i", (int)ListType); + + BufferCache.WriteByte(ListType); + BufferCache.WriteBEInt(ListLength); + + if ((ListType <= eTagType::TAG_Min) || (ListType > eTagType::TAG_Max)) + { + // Bad tag type + return Data; + } + + for (int i = 0; i < ListLength; i++) + { + AString EntryData = ReadNBTDataFromBuffer(a_ByteBuffer, ListType); + BufferCache.WriteBuf(EntryData.data(), EntryData.size()); + } + break; + } + case eTagType::TAG_String: + { + // Read the following string length: + short StrLength; + if (!a_ByteBuffer.ReadBEShort(StrLength)) + { + // Can't read string length + return Data; + } + BufferCache.WriteBEShort(StrLength); + TagLength += (size_t)StrLength; + break; + } + case eTagType::TAG_ByteArray: + { + int ArrayLength; + if (!a_ByteBuffer.ReadBEInt(ArrayLength) || (ArrayLength < 0) || (ArrayLength >= 16777216)) + { + // Bad array length + return Data; + } + BufferCache.WriteBEInt(ArrayLength); + TagLength += (size_t) ArrayLength; + break; + } + case eTagType::TAG_IntArray: + { + int ArrayLength; + if (!a_ByteBuffer.ReadBEInt(ArrayLength) || (ArrayLength < 0) || (ArrayLength >= 16777216)) + { + // Bad array length + return Data; + } + BufferCache.WriteBEInt(ArrayLength); + TagLength += (size_t)ArrayLength * sizeof(int); + break; + } + } + + // Copy tag bytes to the cache: + AString TagBytes; + if (!a_ByteBuffer.ReadString(TagBytes, TagLength)) + { + break; + } + BufferCache.WriteBuf(TagBytes.data(), TagBytes.size()); + + // Write cache to Data and clean: + AString Bytes; + BufferCache.ReadAll(Bytes); + BufferCache.CommitRead(); + Data.append(Bytes.data(), Bytes.size()); + } + + // Read the rest from cache + if (BufferCache.GetUsedSpace() != 0) + { + AString Bytes; + BufferCache.ReadAll(Bytes); + BufferCache.CommitRead(); + Data.append(Bytes.data(), Bytes.size()); + } + + return Data; +} + + + + + void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: @@ -2530,9 +2693,8 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) a_Item.Empty(); } - AString Metadata; - a_ByteBuffer.ReadAll(Metadata); - if ((Metadata.size() == 0) || (Metadata[0] == 0)) + AString Metadata = ReadNBTDataFromBuffer(a_ByteBuffer); + if (Metadata.size() == 0 || (Metadata[0] == 0)) { // No metadata return true; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index fd3121d7f..2275f6298 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -269,6 +269,9 @@ protected: /** The dimension that was last sent to a player in a Respawn or Login packet. Used to avoid Respawning into the same dimension, which confuses the client. */ eDimension m_LastSentDimension; + + /** Read a nbt data from the buffer. (It's needed because the 1.8 protocol doesn't send the nbt length) */ + AString ReadNBTDataFromBuffer(cByteBuffer & a_ByteBuffer, int a_ListTag = 0); /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ -- cgit v1.2.3 From 9cddffb6df595afef1584c92b6d5fc97c9eb162c Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 22 Sep 2014 21:18:13 +0200 Subject: Changed metadata reading again. --- src/Protocol/Protocol18x.cpp | 175 ++----------------------------------------- src/Protocol/Protocol18x.h | 5 +- 2 files changed, 7 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 07e21923c..fbeb845f8 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1652,169 +1652,6 @@ void cProtocol180::FixItemFramePositions(int a_ObjectData, double & a_PosX, doub -AString cProtocol180::ReadNBTDataFromBuffer(cByteBuffer & a_ByteBuffer, int a_ListTag) -{ - cByteBuffer BufferCache(64 KiB); - AString Data; - - while (a_ByteBuffer.GetReadableSpace() != 0) - { - unsigned char TypeID; - if (a_ListTag != 0) - { - TypeID = (unsigned char)a_ListTag; - } - else - { - if (!a_ByteBuffer.ReadByte(TypeID)) - { - // Can't read the next byte - break; - } - BufferCache.WriteByte(TypeID); - } - - if ((TypeID <= eTagType::TAG_Min) || (TypeID > eTagType::TAG_Max)) - { - // Bad type id (or TAG_End) - break; - } - eTagType TagType = static_cast(TypeID); - - // Read the following string length: - if (a_ListTag == 0) - { - short StrLength = 0; - if (!a_ByteBuffer.ReadBEShort(StrLength)) - { - // Can't read string length - return Data; - } - BufferCache.WriteBEShort(StrLength); - - // Read string and write to BufferCache: - AString TagTitle; - if (!a_ByteBuffer.ReadString(TagTitle, (size_t)StrLength)) - { - // Can't read string - return Data; - } - BufferCache.WriteBuf(TagTitle.data(), TagTitle.size()); - } - - size_t TagLength = 0; - switch (TagType) - { - case eTagType::TAG_Byte: TagLength = sizeof(Byte); break; - case eTagType::TAG_Short: TagLength = sizeof(short); break; - case eTagType::TAG_Int: TagLength = sizeof(int); break; - case eTagType::TAG_Long: TagLength = sizeof(long); break; - case eTagType::TAG_Float: TagLength = sizeof(float); break; - case eTagType::TAG_Double: TagLength = sizeof(double); break; - case eTagType::TAG_End: break; - case eTagType::TAG_Compound: - { - AString CompoundData = ReadNBTDataFromBuffer(a_ByteBuffer); - Data.append(CompoundData.data(), CompoundData.size()); - break; - } - case eTagType::TAG_List: - { - Byte ListType; - int ListLength; - if (!a_ByteBuffer.ReadByte(ListType) || !a_ByteBuffer.ReadBEInt(ListLength) || (ListLength < 0)) - { - // Bad list type or list length - return Data; - } - LOGWARNING("LIST, Type: %i", (int)ListType); - - BufferCache.WriteByte(ListType); - BufferCache.WriteBEInt(ListLength); - - if ((ListType <= eTagType::TAG_Min) || (ListType > eTagType::TAG_Max)) - { - // Bad tag type - return Data; - } - - for (int i = 0; i < ListLength; i++) - { - AString EntryData = ReadNBTDataFromBuffer(a_ByteBuffer, ListType); - BufferCache.WriteBuf(EntryData.data(), EntryData.size()); - } - break; - } - case eTagType::TAG_String: - { - // Read the following string length: - short StrLength; - if (!a_ByteBuffer.ReadBEShort(StrLength)) - { - // Can't read string length - return Data; - } - BufferCache.WriteBEShort(StrLength); - TagLength += (size_t)StrLength; - break; - } - case eTagType::TAG_ByteArray: - { - int ArrayLength; - if (!a_ByteBuffer.ReadBEInt(ArrayLength) || (ArrayLength < 0) || (ArrayLength >= 16777216)) - { - // Bad array length - return Data; - } - BufferCache.WriteBEInt(ArrayLength); - TagLength += (size_t) ArrayLength; - break; - } - case eTagType::TAG_IntArray: - { - int ArrayLength; - if (!a_ByteBuffer.ReadBEInt(ArrayLength) || (ArrayLength < 0) || (ArrayLength >= 16777216)) - { - // Bad array length - return Data; - } - BufferCache.WriteBEInt(ArrayLength); - TagLength += (size_t)ArrayLength * sizeof(int); - break; - } - } - - // Copy tag bytes to the cache: - AString TagBytes; - if (!a_ByteBuffer.ReadString(TagBytes, TagLength)) - { - break; - } - BufferCache.WriteBuf(TagBytes.data(), TagBytes.size()); - - // Write cache to Data and clean: - AString Bytes; - BufferCache.ReadAll(Bytes); - BufferCache.CommitRead(); - Data.append(Bytes.data(), Bytes.size()); - } - - // Read the rest from cache - if (BufferCache.GetUsedSpace() != 0) - { - AString Bytes; - BufferCache.ReadAll(Bytes); - BufferCache.CommitRead(); - Data.append(Bytes.data(), Bytes.size()); - } - - return Data; -} - - - - - void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: @@ -2254,7 +2091,7 @@ void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) } cItem Item; - ReadItem(a_ByteBuffer, Item); + ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace() - 3); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); @@ -2328,7 +2165,7 @@ void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffe { HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); cItem Item; - if (!ReadItem(a_ByteBuffer, Item)) + if (!ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace())) { return; } @@ -2581,7 +2418,7 @@ void cProtocol180::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode); cItem Item; - ReadItem(a_ByteBuffer, Item); + ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace()); // Convert Button, Mode, SlotNum and HeldItem into eClickAction: eClickAction Action; @@ -2673,7 +2510,7 @@ void cProtocol180::SendData(const char * a_Data, size_t a_Size) -bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) +bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_MetadataSize) { HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); if (ItemType == -1) @@ -2693,8 +2530,8 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) a_Item.Empty(); } - AString Metadata = ReadNBTDataFromBuffer(a_ByteBuffer); - if (Metadata.size() == 0 || (Metadata[0] == 0)) + AString Metadata; + if (!a_ByteBuffer.ReadString(Metadata, a_MetadataSize) || (Metadata.size() == 0) || (Metadata[0] == 0)) { // No metadata return true; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 2275f6298..59a5dd0b6 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -269,9 +269,6 @@ protected: /** The dimension that was last sent to a player in a Respawn or Login packet. Used to avoid Respawning into the same dimension, which confuses the client. */ eDimension m_LastSentDimension; - - /** Read a nbt data from the buffer. (It's needed because the 1.8 protocol doesn't send the nbt length) */ - AString ReadNBTDataFromBuffer(cByteBuffer & a_ByteBuffer, int a_ListTag = 0); /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ @@ -325,7 +322,7 @@ protected: void SendCompass(const cWorld & a_World); /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ - virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_MetadataSize = 1); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); -- cgit v1.2.3 From fc11818f4c9eaeb9eb1acab4fcc3c6776e6c2d00 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 22 Sep 2014 22:06:08 +0200 Subject: Hotfixed 1.8 item reading. --- src/Protocol/Protocol18x.cpp | 10 +++++----- src/Protocol/Protocol18x.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index fbeb845f8..a7ab3abb1 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2091,7 +2091,7 @@ void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) } cItem Item; - ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace() - 3); + ReadItem(a_ByteBuffer, Item, 3); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); @@ -2165,7 +2165,7 @@ void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffe { HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); cItem Item; - if (!ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace())) + if (!ReadItem(a_ByteBuffer, Item)) { return; } @@ -2418,7 +2418,7 @@ void cProtocol180::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode); cItem Item; - ReadItem(a_ByteBuffer, Item, a_ByteBuffer.GetReadableSpace()); + ReadItem(a_ByteBuffer, Item); // Convert Button, Mode, SlotNum and HeldItem into eClickAction: eClickAction Action; @@ -2510,7 +2510,7 @@ void cProtocol180::SendData(const char * a_Data, size_t a_Size) -bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_MetadataSize) +bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes) { HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); if (ItemType == -1) @@ -2531,7 +2531,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a } AString Metadata; - if (!a_ByteBuffer.ReadString(Metadata, a_MetadataSize) || (Metadata.size() == 0) || (Metadata[0] == 0)) + if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_RemainingBytes) || (Metadata.size() == 0) || (Metadata[0] == 0)) { // No metadata return true; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 59a5dd0b6..eb0253663 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -322,7 +322,7 @@ protected: void SendCompass(const cWorld & a_World); /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ - virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_MetadataSize = 1); + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes = 0); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); -- cgit v1.2.3 From 1aa64f32e1bea1620b721d9bd86e9fc315738ea3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 22 Sep 2014 22:07:58 +0200 Subject: Updated README.md --- src/Protocol/ProtocolRecognizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 3177f06ae..55348a758 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -18,7 +18,7 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10" +#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10, 1.8" #define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5" -- cgit v1.2.3 From 806871b86f2f04545f20caa6a8c30db2ccb7bc12 Mon Sep 17 00:00:00 2001 From: Chris Darnell Date: Mon, 22 Sep 2014 18:23:56 -0400 Subject: A few compiler warning fixes --- src/BlockEntities/RedstonePoweredEntity.h | 2 +- src/Entities/Entity.cpp | 5 +- src/Entities/EntityEffect.cpp | 1 + src/Entities/Minecart.cpp | 81 ++++++++++++++++--------------- src/Tracer.cpp | 2 +- 5 files changed, 47 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/RedstonePoweredEntity.h b/src/BlockEntities/RedstonePoweredEntity.h index f11df4fc4..eac4e35d4 100644 --- a/src/BlockEntities/RedstonePoweredEntity.h +++ b/src/BlockEntities/RedstonePoweredEntity.h @@ -6,7 +6,7 @@ class cRedstonePoweredEntity { public: - virtual ~cRedstonePoweredEntity() {}; + virtual ~cRedstonePoweredEntity() {} /// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate virtual void SetRedstonePower(bool a_IsPowered) = 0; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index c8ebc4314..8ef24828e 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -342,6 +342,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel); break; } + default: break; } } } @@ -1015,7 +1016,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f; if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f; - if (Tracer.HitNormal.y == 1) // Hit BLOCK_FACE_YP, we are on the ground + if (Tracer.HitNormal.y == 1.f) // Hit BLOCK_FACE_YP, we are on the ground { m_bOnGround = true; } @@ -1960,7 +1961,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways) { return; } - if ((a_Forward != 0) || (a_Sideways != 0)) + if ((a_Forward != 0.f) || (a_Sideways != 0.f)) { m_AttachedTo->HandleSpeedFromAttachee(a_Forward, a_Sideways); } diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 1a923930f..98c5d23b4 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -96,6 +96,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) base = 1800; break; } + default: break; } // If potion is level II, half the duration. If not, stays the same diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index bc9e21d8e..5833cb4ae 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -13,6 +13,7 @@ #include "Player.h" #include "../BoundingBox.h" +#define NO_SPEED 0.0 #define MAX_SPEED 8 #define MAX_SPEED_NEGATIVE -MAX_SPEED @@ -220,7 +221,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedZ() != 0) // Don't do anything if cart is stationary + if (GetSpeedZ() != NO_SPEED) // Don't do anything if cart is stationary { if (GetSpeedZ() > 0) { @@ -239,13 +240,13 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(180); SetPosY(floor(GetPosY()) + 0.55); - SetSpeedY(0); - SetSpeedZ(0); + SetSpeedY(NO_SPEED); + SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedX() != 0) + if (GetSpeedX() != NO_SPEED) { if (GetSpeedX() > 0) { @@ -305,9 +306,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() >= 0) + if (GetSpeedX() >= NO_SPEED) { if (GetSpeedX() <= MAX_SPEED) { @@ -424,9 +425,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedZ() != 0) + if (GetSpeedZ() != NO_SPEED) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { AddSpeedZ(AccelDecelSpeed); } @@ -441,15 +442,15 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { SetYaw(180); SetPosY(floor(GetPosY()) + 0.55); - SetSpeedY(0); - SetSpeedZ(0); + SetSpeedY(NO_SPEED); + SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedX() != 0) + if (GetSpeedX() != NO_SPEED) { - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { AddSpeedX(AccelDecelSpeed); } @@ -463,9 +464,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() >= 0) + if (GetSpeedX() >= NO_SPEED) { if (GetSpeedX() <= MAX_SPEED) { @@ -483,9 +484,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XP: // ASCEND WEST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { AddSpeedX(AccelDecelSpeed); SetSpeedY(GetSpeedX()); @@ -503,9 +504,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH { SetYaw(270); - SetSpeedX(0); + SetSpeedX(NO_SPEED); - if (GetSpeedZ() >= 0) + if (GetSpeedZ() >= NO_SPEED) { if (GetSpeedZ() <= MAX_SPEED) { @@ -523,9 +524,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH { SetYaw(270); - SetSpeedX(0); + SetSpeedX(NO_SPEED); - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { AddSpeedZ(AccelDecelSpeed); SetSpeedY(GetSpeedZ()); @@ -576,7 +577,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XP: case E_META_RAIL_XM_XP: { - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); break; } @@ -584,7 +585,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZP: case E_META_RAIL_ZM_ZP: { - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); break; } @@ -593,12 +594,12 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) { if (GetPosZ() > floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { SetSpeedX(-GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() > floor(GetPosX()) + 0.5) @@ -608,82 +609,82 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedZ(-GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZM_XP: { if (GetPosZ() > floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { SetSpeedX(GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() < floor(GetPosX()) + 0.5) { - if (GetSpeedX() < 0) + if (GetSpeedX() < NO_SPEED) { SetSpeedZ(GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZP_XM: { if (GetPosZ() < floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() < 0) + if (GetSpeedZ() < NO_SPEED) { SetSpeedX(GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() > floor(GetPosX()) + 0.5) { - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { SetSpeedZ(GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZP_XP: { if (GetPosZ() < floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() < 0) + if (GetSpeedZ() < NO_SPEED) { SetSpeedX(-GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() < floor(GetPosX()) + 0.5) { - if (GetSpeedX() < 0) + if (GetSpeedX() < NO_SPEED) { SetSpeedZ(-GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } SetSpeedY(0); diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 8ccd18071..e125c6aa4 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -283,7 +283,7 @@ int cTracer::intersect3D_SegmentPlane( const Vector3f & a_Origin, const Vector3f if (fabs(D) < EPSILON) { // segment is parallel to plane - if (N == 0) + if (N == 0.0) { // segment lies in plane return 2; -- cgit v1.2.3 From 5f6bac20915fda0d0a92c805f6dfbf562bb4beee Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 23 Sep 2014 00:12:28 -0700 Subject: Made ExpBottleEntity break on entities. Fixes #1369 --- src/Entities/ExpBottleEntity.cpp | 19 ++++++++++++++++++- src/Entities/ExpBottleEntity.h | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/ExpBottleEntity.cpp b/src/Entities/ExpBottleEntity.cpp index 202dde942..ee142a5a2 100644 --- a/src/Entities/ExpBottleEntity.cpp +++ b/src/Entities/ExpBottleEntity.cpp @@ -18,10 +18,27 @@ cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y, void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) +{ + Break(a_HitPos); +} + + + + + +void cExpBottleEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) +{ + Break(a_HitPos); +} + + + + + +void cExpBottleEntity::Break(const Vector3d &a_HitPos) { // Spawn an experience orb with a reward between 3 and 11. m_World->BroadcastSoundParticleEffect(2002, POSX_TOINT, POSY_TOINT, POSZ_TOINT, 0); m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), 3 + m_World->GetTickRandomNumber(8)); - Destroy(); } diff --git a/src/Entities/ExpBottleEntity.h b/src/Entities/ExpBottleEntity.h index d62a84469..d36110f97 100644 --- a/src/Entities/ExpBottleEntity.h +++ b/src/Entities/ExpBottleEntity.h @@ -29,5 +29,10 @@ protected: // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; + virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override; + + /** Breaks the bottle, fires its particle effects and sounds + @param a_HitPos The position where the bottle will break */ + void Break(const Vector3d &a_HitPos); }; // tolua_export -- cgit v1.2.3 From 366af5067b987e7d4ad233e258b9e93d6f472afe Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 23 Sep 2014 19:16:17 +0200 Subject: MCServer world compatiblity with vanilla and mcedit. --- src/WorldStorage/NBTChunkSerializer.cpp | 16 ++++++++++++++ src/WorldStorage/NBTChunkSerializer.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 39 ++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 1962d42ff..09225dd90 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -765,6 +765,22 @@ void cNBTChunkSerializer::LightIsValid(bool a_IsLightValid) +void cNBTChunkSerializer::HeightMap(const cChunkDef::HeightMap * a_HeightMap) +{ + for (int RelX = 0; RelX < cChunkDef::Width; RelX++) + { + for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++) + { + int Height = cChunkDef::GetHeight(*a_HeightMap, RelX, RelZ); + m_VanillaHeightMap[(RelZ << 4) | RelX] = Height; + } + } +} + + + + + void cNBTChunkSerializer::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) { memcpy(m_Biomes, a_BiomeMap, sizeof(m_Biomes)); diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 4c229a65c..5ffab8cc5 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -59,6 +59,7 @@ class cNBTChunkSerializer : public: cChunkDef::BiomeMap m_Biomes; unsigned char m_VanillaBiomes[cChunkDef::Width * cChunkDef::Width]; + int m_VanillaHeightMap[cChunkDef::Width * cChunkDef::Width]; bool m_BiomesAreValid; @@ -125,6 +126,7 @@ protected: // cChunkDataSeparateCollector overrides: virtual void LightIsValid(bool a_IsLightValid) override; + virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override; virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override; virtual void Entity(cEntity * a_Entity) override; virtual void BlockEntity(cBlockEntity * a_Entity) override; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 10cc39083..8dc4088b7 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -96,10 +96,26 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : if (!cFile::Exists(fnam)) { cFastNBTWriter Writer; - Writer.BeginCompound(""); - Writer.AddInt("SpawnX", (int)(a_World->GetSpawnX())); - Writer.AddInt("SpawnY", (int)(a_World->GetSpawnY())); - Writer.AddInt("SpawnZ", (int)(a_World->GetSpawnZ())); + Writer.BeginCompound("Data"); + Writer.AddByte("allowCommands", 1); + Writer.AddByte("Difficulty", 2); + Writer.AddByte("hardcore", 0); + Writer.AddByte("initialized", 1); + Writer.AddByte("MapFeatures", 1); + Writer.AddByte("raining", a_World->IsWeatherRain() ? 1 : 0); + Writer.AddByte("thundering", a_World->IsWeatherStorm() ? 1 : 0); + Writer.AddInt("GameType", (int)a_World->GetGameMode()); + Writer.AddInt("generatorVersion", 1); + Writer.AddInt("SpawnX", (int)a_World->GetSpawnX()); + Writer.AddInt("SpawnY", (int)a_World->GetSpawnY()); + Writer.AddInt("SpawnZ", (int)a_World->GetSpawnZ()); + Writer.AddInt("version", 19133); + Writer.AddLong("DayTime", (Int64)a_World->GetTimeOfDay()); + Writer.AddLong("Time", a_World->GetWorldAge()); + Writer.AddLong("SizeOnDisk", 0); + Writer.AddString("generatorName", "default"); + Writer.AddString("generatorOptions", ""); + Writer.AddString("LevelName", a_World->GetName()); Writer.EndCompound(); Writer.Finish(); @@ -440,6 +456,13 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ a_Writer.BeginCompound("Level"); a_Writer.AddInt("xPos", a_Chunk.m_ChunkX); a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ); + + // Add "Entities" and "TileEntities". MCEdit can't load the chunk if one of these lists doesn't exists. + a_Writer.BeginList("Entities", TAG_Compound); + a_Writer.EndList(); + a_Writer.BeginList("TileEntities", TAG_Compound); + a_Writer.EndList(); + cNBTChunkSerializer Serializer(a_Writer); if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) { @@ -454,7 +477,10 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ a_Writer.AddByteArray("Biomes", (const char *)(Serializer.m_VanillaBiomes), ARRAYCOUNT(Serializer.m_VanillaBiomes)); a_Writer.AddIntArray ("MCSBiomes", (const int *)(Serializer.m_Biomes), ARRAYCOUNT(Serializer.m_Biomes)); } - + + // Save heightmap (Vanilla require this): + a_Writer.AddIntArray("HeightMap", (const int *)Serializer.m_VanillaHeightMap, ARRAYCOUNT(Serializer.m_VanillaHeightMap)); + // Save blockdata: a_Writer.BeginList("Sections", TAG_Compound); size_t SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16; @@ -485,6 +511,9 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ { a_Writer.AddByte("MCSIsLightValid", 1); } + + // Save the world age to the chunk data. Required by vanilla and mcedit. + a_Writer.AddLong("LastUpdate", m_World->GetWorldAge()); // Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete. a_Writer.AddByte("TerrainPopulated", 1); -- cgit v1.2.3 From 0b40ce971c85eb7037250b03bab01a66536e7b05 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 23 Sep 2014 22:11:25 +0200 Subject: Fixed a crash in WSSAnvil. Reported as #1448. --- src/WorldStorage/WSSAnvil.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 10cc39083..e132a0c26 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2464,19 +2464,19 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N LoadWolfOwner(*Monster.get(), a_NBT, a_TagIdx); int SittingIdx = a_NBT.FindChildByName(a_TagIdx, "Sitting"); - if (SittingIdx > 0) + if ((SittingIdx > 0) && (a_NBT.GetType(SittingIdx) == TAG_Byte)) { bool Sitting = ((a_NBT.GetByte(SittingIdx) == 1) ? true : false); Monster->SetIsSitting(Sitting); } int AngryIdx = a_NBT.FindChildByName(a_TagIdx, "Angry"); - if (AngryIdx > 0) + if ((AngryIdx > 0) && (a_NBT.GetType(AngryIdx) == TAG_Byte)) { bool Angry = ((a_NBT.GetByte(AngryIdx) == 1) ? true : false); Monster->SetIsAngry(Angry); } int CollarColorIdx = a_NBT.FindChildByName(a_TagIdx, "CollarColor"); - if (CollarColorIdx > 0) + if ((CollarColorIdx > 0) && (a_NBT.GetType(CollarColorIdx) == TAG_Int)) { int CollarColor = a_NBT.GetInt(CollarColorIdx); Monster->SetCollarColor(CollarColor); -- cgit v1.2.3 From d04ab9b70300e9c7fc5cddeac648fde3aa7d3450 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 23 Sep 2014 22:12:24 +0200 Subject: Fixed compiler warnings in 1.8 protocol. --- src/Protocol/Protocol18x.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index e2ea6701a..f62d350fe 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -576,7 +576,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) // Send the spawn position: { cPacketizer Pkt(*this, 0x05); // Spawn Position packet - Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ()); + Pkt.WritePosition((int)a_World.GetSpawnX(), (int)a_World.GetSpawnY(), (int)a_World.GetSpawnZ()); } // Send the server difficulty: @@ -633,7 +633,7 @@ void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) cPacketizer Pkt(*this, 0x10); // Spawn Painting packet Pkt.WriteVarInt(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName().c_str()); - Pkt.WritePosition(PosX, PosY, PosZ); + Pkt.WritePosition((int)PosX, (int)PosY, (int)PosZ); Pkt.WriteChar(a_Painting.GetDirection()); } -- cgit v1.2.3 From 8d9dfc5d1a090f163f927484a43baaad49052f31 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 23 Sep 2014 22:22:38 +0200 Subject: Anvil: Wolf collar color is a byte in Vanilla. Kept the old Int reading for compatibility reasons. Ref.: #1448 --- src/WorldStorage/NBTChunkSerializer.cpp | 2 +- src/WorldStorage/WSSAnvil.cpp | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 1962d42ff..3c9da6de7 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -582,7 +582,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) } m_Writer.AddByte("Sitting", Wolf.IsSitting() ? 1 : 0); m_Writer.AddByte("Angry", Wolf.IsAngry() ? 1 : 0); - m_Writer.AddInt("CollarColor", Wolf.GetCollarColor()); + m_Writer.AddByte("CollarColor", (unsigned char)Wolf.GetCollarColor()); break; } case cMonster::mtZombie: diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index e132a0c26..be526e74e 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2476,10 +2476,24 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N Monster->SetIsAngry(Angry); } int CollarColorIdx = a_NBT.FindChildByName(a_TagIdx, "CollarColor"); - if ((CollarColorIdx > 0) && (a_NBT.GetType(CollarColorIdx) == TAG_Int)) + if (CollarColorIdx > 0) { - int CollarColor = a_NBT.GetInt(CollarColorIdx); - Monster->SetCollarColor(CollarColor); + switch (a_NBT.GetType(CollarColorIdx)) + { + case TAG_Byte: + { + // Vanilla uses this + unsigned char CollarColor = a_NBT.GetByte(CollarColorIdx); + Monster->SetCollarColor(CollarColor); + break; + } + case TAG_Int: + { + // Old MCS code used this, keep reading it for compatibility reasons: + Monster->SetCollarColor(a_NBT.GetInt(CollarColorIdx)); + break; + } + } } a_Entities.push_back(Monster.release()); } -- cgit v1.2.3 From 1d588b5195507f52c25d57a627c3304c024770ce Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 24 Sep 2014 15:17:20 +0200 Subject: Don't create two entity lists. --- src/WorldStorage/NBTChunkSerializer.cpp | 12 ++++++++++++ src/WorldStorage/WSSAnvil.cpp | 9 ++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 0e364d8b0..a052bf5f3 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -81,6 +81,18 @@ void cNBTChunkSerializer::Finish(void) memset(m_BlockLight, 0, sizeof(m_BlockLight)); memset(m_BlockSkyLight, 0, sizeof(m_BlockSkyLight)); } + + // Check if "Entity" and "TileEntities" lists exists. MCEdit requires this. + if (!m_HasHadEntity) + { + a_Writer.BeginList("Entities", TAG_Compound); + a_Writer.EndList(); + } + if (!m_HasHadBlockEntity) + { + a_Writer.BeginList("TileEntities", TAG_Compound); + a_Writer.EndList(); + } } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 3821ad976..bd814e2c7 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -51,6 +51,7 @@ #include "../Entities/ItemFrame.h" #include "../Protocol/MojangAPI.h" +#include "Server.h" @@ -99,7 +100,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : Writer.BeginCompound("Data"); Writer.AddByte("allowCommands", 1); Writer.AddByte("Difficulty", 2); - Writer.AddByte("hardcore", 0); + Writer.AddByte("hardcore", cRoot::Get()->GetServer()->IsHardcore() ? 1 : 0); Writer.AddByte("initialized", 1); Writer.AddByte("MapFeatures", 1); Writer.AddByte("raining", a_World->IsWeatherRain() ? 1 : 0); @@ -457,12 +458,6 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ a_Writer.AddInt("xPos", a_Chunk.m_ChunkX); a_Writer.AddInt("zPos", a_Chunk.m_ChunkZ); - // Add "Entities" and "TileEntities". MCEdit can't load the chunk if one of these lists doesn't exists. - a_Writer.BeginList("Entities", TAG_Compound); - a_Writer.EndList(); - a_Writer.BeginList("TileEntities", TAG_Compound); - a_Writer.EndList(); - cNBTChunkSerializer Serializer(a_Writer); if (!m_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) { -- cgit v1.2.3 From 32ecb121a3f7e0fa2cd35c78403949947e889c1d Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 24 Sep 2014 15:30:52 +0200 Subject: derp --- src/WorldStorage/NBTChunkSerializer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index a052bf5f3..08ed893f5 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -85,13 +85,13 @@ void cNBTChunkSerializer::Finish(void) // Check if "Entity" and "TileEntities" lists exists. MCEdit requires this. if (!m_HasHadEntity) { - a_Writer.BeginList("Entities", TAG_Compound); - a_Writer.EndList(); + m_Writer.BeginList("Entities", TAG_Compound); + m_Writer.EndList(); } if (!m_HasHadBlockEntity) { - a_Writer.BeginList("TileEntities", TAG_Compound); - a_Writer.EndList(); + m_Writer.BeginList("TileEntities", TAG_Compound); + m_Writer.EndList(); } } -- cgit v1.2.3 From 799c96661d7dc8ea89517fa0be205e72ea2f717e Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 25 Sep 2014 15:45:39 +0100 Subject: Fixed style --- src/BlockInfo.h | 4 +- src/Blocks/ChunkInterface.cpp | 66 ++++++++++++++++++++++++++++++ src/Blocks/GetHandlerCompileTimeTemplate.h | 37 +++++++++++++++++ src/Mobs/Monster.h | 3 ++ 4 files changed, 108 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.h b/src/BlockInfo.h index bfa62a132..1e4cf2ca0 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -19,8 +19,8 @@ public: /** Returns the associated BlockInfo structure for the specified block type. */ /** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. -It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. -It works only if it is called for the first time before the app spawns other threads. */ + It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. + It works only if it is called for the first time before the app spawns other threads. */ static cBlockInfo & Get(BLOCKTYPE a_Type) { static cBlockInfo ms_Info[256]; diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index a4c96a478..5ac4dcf80 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -5,24 +5,49 @@ #include "ChunkMap.h" #include "BlockHandler.h" + + + + + BLOCKTYPE cChunkInterface::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ); } + + + + + BLOCKTYPE cChunkInterface::GetBlock(const Vector3i & a_Pos) { return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z); } + + + + + NIBBLETYPE cChunkInterface::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); } + + + + + bool cChunkInterface::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } + + + + + /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ @@ -31,16 +56,31 @@ void cChunkInterface::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } + + + + + void cChunkInterface::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) { m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData); } + + + + + void cChunkInterface::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface) { m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType); } + + + + + /** Sets the block at the specified coords to the specified value. The replacement doesn't trigger block updates. The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block) @@ -50,29 +90,55 @@ void cChunkInterface::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } + + + + + void cChunkInterface::FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); } + + + + + void cChunkInterface::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } + + + + + bool cChunkInterface::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) { return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback); } + + + + + bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) { return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes); } + + + + + bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z) { cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); } + diff --git a/src/Blocks/GetHandlerCompileTimeTemplate.h b/src/Blocks/GetHandlerCompileTimeTemplate.h index 658497bf2..3466b5426 100644 --- a/src/Blocks/GetHandlerCompileTimeTemplate.h +++ b/src/Blocks/GetHandlerCompileTimeTemplate.h @@ -8,9 +8,20 @@ class cBlockTripwireHookHandler; class cBlockDoorHandler; class cBlockPistonHandler; + + + + + template class GetHandlerCompileTime; + + + + + + template<> class GetHandlerCompileTime { @@ -18,6 +29,11 @@ public: typedef cBlockTorchHandler type; }; + + + + + template<> class GetHandlerCompileTime { @@ -25,6 +41,11 @@ public: typedef cBlockLeverHandler type; }; + + + + + template<> class GetHandlerCompileTime { @@ -32,6 +53,11 @@ public: typedef cBlockButtonHandler type; }; + + + + + template<> class GetHandlerCompileTime { @@ -39,6 +65,11 @@ public: typedef cBlockTripwireHookHandler type; }; + + + + + template<> class GetHandlerCompileTime { @@ -46,9 +77,15 @@ public: typedef cBlockDoorHandler type; }; + + + + + template<> class GetHandlerCompileTime { public: typedef cBlockPistonHandler type; }; + diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 9fd67d67c..ba746ebc8 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -25,6 +25,9 @@ class cMonster : typedef cPawn super; public: + //Depreciated + typedef eMonsterType eType; + enum eFamily { mfHostile = 0, // Spider, Zombies ... -- cgit v1.2.3 From 843f31ecbace5b78486cb72df9404e0bfec900df Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 18:33:01 +0200 Subject: HangingEntity: Silenced a crash. Vanilla worlds sometimes contain data that this was asserting upon. Changed into a log. --- src/Entities/HangingEntity.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/HangingEntity.cpp b/src/Entities/HangingEntity.cpp index 8c70c606e..6e9a89550 100644 --- a/src/Entities/HangingEntity.cpp +++ b/src/Entities/HangingEntity.cpp @@ -28,11 +28,17 @@ void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle) // The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces switch (m_BlockFace) { - case BLOCK_FACE_ZP: break; // Initialised to zero + case BLOCK_FACE_ZP: Dir = 0; break; case BLOCK_FACE_ZM: Dir = 2; break; case BLOCK_FACE_XM: Dir = 1; break; case BLOCK_FACE_XP: Dir = 3; break; - default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return; + default: + { + LOGINFO("Invalid face (%d) in a cHangingEntity at {%d, %d, %d}, adjusting to BLOCK_FACE_XP.", + m_BlockFace, (int)GetPosX(), (int)GetPosY(), (int)GetPosZ() + ); + Dir = 3; + } } if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180 -- cgit v1.2.3 From a518a83c258897d5f2e0d769aa7fce8c30befafb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 18:33:34 +0200 Subject: 1.7 Protocol: fixed potential problems with no-payload packets. --- src/Protocol/Protocol17x.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 67a4c47a7..73d2a74f9 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1519,9 +1519,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); m_ReceivedData.CommitRead(); - // Write one NUL extra, so that we can detect over-reads - bb.Write("\0", 1); - UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) { @@ -1529,6 +1526,9 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) break; } + // Write one NUL extra, so that we can detect over-reads + bb.Write("\0", 1); + // Log the packet info into the comm log file: if (g_ShouldLogCommIn) { @@ -1536,7 +1536,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) bb.ReadAll(PacketData); bb.ResetRead(); bb.ReadVarInt(PacketType); - ASSERT(PacketData.size() > 0); + ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read PacketData.resize(PacketData.size() - 1); AString PacketDataHex; CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); -- cgit v1.2.3 From aeabc4ff6b19384df47031fc995cd8ac988c2e0a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 18:34:40 +0200 Subject: 1.8 Protocol: Fixed problems with no-payload packets. --- src/Protocol/Protocol18x.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index f62d350fe..94eaa43db 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1711,7 +1711,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) m_ReceivedData.ResetRead(); break; } - cByteBuffer bb(PacketLen); + cByteBuffer bb(PacketLen + 1); VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); m_ReceivedData.CommitRead(); @@ -1726,9 +1726,6 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) } } - // Write one NUL extra, so that we can detect over-reads - bb.Write("\0", 1); - UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) { @@ -1736,6 +1733,9 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) break; } + // Write one NUL extra, so that we can detect over-reads + bb.Write("\0", 1); + // Log the packet info into the comm log file: if (g_ShouldLogCommIn) { @@ -1743,7 +1743,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) bb.ReadAll(PacketData); bb.ResetRead(); bb.ReadVarInt(PacketType); - ASSERT(PacketData.size() > 0); + ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read PacketData.resize(PacketData.size() - 1); AString PacketDataHex; CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); @@ -1777,7 +1777,8 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) return; } - if (bb.GetReadableSpace() != 0) + // The packet should have 1 byte left in the buffer - the NUL we had added + if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", -- cgit v1.2.3 From c6f78d516b356c9ea1137331fbd5eff0762aa1a9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 18:35:41 +0200 Subject: Redstone: Fixed a crash with repeaters on a chunk border. --- src/Simulator/IncrementalRedstoneSimulator.cpp | 35 ++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 7b3a2c2fa..8649a1841 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1619,17 +1619,22 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB { // Check if eastern(right) neighbor is a powered on repeater who is facing us BLOCKTYPE Block = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater? + NIBBLETYPE OtherRepeaterDir = 0; + if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater? { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3; - if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked + if ((OtherRepeaterDir & 0x03) == 0x03) + { + return true; + } // If so, I am latched/locked } // Check if western(left) neighbor is a powered on repeater who is facing us - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3; - if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked + if ((OtherRepeaterDir & 0x03) == 0x01) + { + return true; + } // If so, I am latched/locked } break; @@ -1641,19 +1646,23 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB { // Check if southern(down) neighbor is a powered on repeater who is facing us BLOCKTYPE Block = 0; - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + NIBBLETYPE OtherRepeaterDir = 0; + if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3; - if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked + if ((OtherRepeaterDir & 0x03) == 0x00) + { + return true; + } // If so, am latched/locked } // Check if northern(up) neighbor is a powered on repeater who is facing us - if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) + if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) { - NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3; - if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked + if ((OtherRepeaterDir & 0x03) == 0x02) + { + return true; + } // If so, I am latched/locked } - break; } } -- cgit v1.2.3 From daf5127b28f3c6884e94fc066b3e5e117a6b5d35 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 18:37:24 +0200 Subject: Fixed hanging direction bugs. --- src/Entities/HangingEntity.cpp | 15 +++++++++++++++ src/Entities/HangingEntity.h | 2 +- src/WorldStorage/WSSAnvil.cpp | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/HangingEntity.cpp b/src/Entities/HangingEntity.cpp index 8c70c606e..e789f5f18 100644 --- a/src/Entities/HangingEntity.cpp +++ b/src/Entities/HangingEntity.cpp @@ -21,6 +21,21 @@ cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, +void cHangingEntity::SetDirection(eBlockFace a_BlockFace) +{ + if ((a_BlockFace < 2) || (a_BlockFace > 5)) + { + ASSERT(!"Tried to set a bad direction!"); + return; + } + + m_BlockFace = a_BlockFace; +} + + + + + void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle) { int Dir = 0; diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h index 3593f9ede..455f2f23f 100644 --- a/src/Entities/HangingEntity.h +++ b/src/Entities/HangingEntity.h @@ -24,7 +24,7 @@ public: eBlockFace GetDirection() const { return m_BlockFace; } // tolua_export /** Set the orientation from the hanging entity */ - void SetDirection(eBlockFace a_BlockFace) { m_BlockFace = a_BlockFace; } // tolua_export + void SetDirection(eBlockFace a_BlockFace); // tolua_export /** Returns the X coord. */ int GetTileX() const { return POSX_TOINT; } // tolua_export diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index bd814e2c7..7a9490cd4 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1664,7 +1664,7 @@ void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT if (Direction > 0) { Direction = (int)a_NBT.GetByte(Direction); - if ((Direction < 0) || (Direction > 5)) + if ((Direction < 2) || (Direction > 5)) { a_Hanging.SetDirection(BLOCK_FACE_NORTH); } -- cgit v1.2.3 From 67fe834499b2f0f93cdba1132a80ccb1924e199c Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 18:37:36 +0200 Subject: Fixed dispender direction bug --- src/BlockEntities/DispenserEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index c02c68afa..f8830bf25 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -203,7 +203,7 @@ void cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta) { - switch (a_Meta) + switch (a_Meta & 0x7) { case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0); case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0); -- cgit v1.2.3 From 12621e3800ec353bca179243d521580e0da6eae9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 18:49:55 +0200 Subject: Use the json writer to write sign texts. Without this change the client disconnects if the text contains " --- src/Protocol/Protocol18x.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index f62d350fe..a92ab5f54 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1391,13 +1391,18 @@ void cProtocol180::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) void cProtocol180::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x33); Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ); - Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line1.c_str())); - Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line2.c_str())); - Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line3.c_str())); - Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line4.c_str())); + + Json::StyledWriter JsonWriter; + AString Lines[] = { a_Line1, a_Line2, a_Line3, a_Line4 }; + for (size_t i = 0; i < ARRAYCOUNT(Lines); i++) + { + Json::Value RootValue; + RootValue["text"] = Lines[i]; + Pkt.WriteString(JsonWriter.write(RootValue).c_str()); + } } -- cgit v1.2.3 From 7cdcf0a8833b56a98d60a87a341607fed988cac7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 19:01:44 +0200 Subject: Anvil: Arrow Tile tags are a short in Vanilla --- src/WorldStorage/NBTChunkSerializer.cpp | 6 +++--- src/WorldStorage/WSSAnvil.cpp | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 08ed893f5..849e9eb77 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -637,9 +637,9 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) { cArrowEntity * Arrow = (cArrowEntity *)a_Projectile; - m_Writer.AddInt("xTile", (Int16)Arrow->GetBlockHit().x); - m_Writer.AddInt("yTile", (Int16)Arrow->GetBlockHit().y); - m_Writer.AddInt("zTile", (Int16)Arrow->GetBlockHit().z); + m_Writer.AddShort("xTile", (Int16)Arrow->GetBlockHit().x); + m_Writer.AddShort("yTile", (Int16)Arrow->GetBlockHit().y); + m_Writer.AddShort("zTile", (Int16)Arrow->GetBlockHit().z); m_Writer.AddByte("pickup", Arrow->GetPickupState()); m_Writer.AddDouble("damage", Arrow->GetDamageCoeff()); break; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a9490cd4..092b9514c 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1752,7 +1752,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ // Load pickup state: int PickupIdx = a_NBT.FindChildByName(a_TagIdx, "pickup"); - if (PickupIdx > 0) + if ((PickupIdx > 0) && (a_NBT.GetType(PickupIdx) == TAG_Byte)) { Arrow->SetPickupState((cArrowEntity::ePickupState)a_NBT.GetByte(PickupIdx)); } @@ -1760,7 +1760,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { // Try the older "player" tag: int PlayerIdx = a_NBT.FindChildByName(a_TagIdx, "player"); - if (PlayerIdx > 0) + if ((PlayerIdx > 0) && (a_NBT.GetType(PlayerIdx) == TAG_Byte)) { Arrow->SetPickupState((a_NBT.GetByte(PlayerIdx) == 0) ? cArrowEntity::psNoPickup : cArrowEntity::psInSurvivalOrCreative); } @@ -1768,7 +1768,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ // Load damage: int DamageIdx = a_NBT.FindChildByName(a_TagIdx, "damage"); - if (DamageIdx > 0) + if ((DamageIdx > 0) && (a_NBT.GetType(DamageIdx) == TAG_Double)) { Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx)); } @@ -1779,7 +1779,24 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile"); if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0)) { - Arrow->SetBlockHit(Vector3i(a_NBT.GetInt(InBlockXIdx), a_NBT.GetInt(InBlockYIdx), a_NBT.GetInt(InBlockZIdx))); + if (a_NBT.GetType(InBlockXIdx) == a_NBT.GetType(InBlockYIdx) == a_NBT.GetType(InBlockZIdx)) + { + switch (a_NBT.GetType(InBlockXIdx)) + { + case TAG_Int: + { + // Old MCS code used this, keep reading it for compatibility reasons: + Arrow->SetBlockHit(Vector3i(a_NBT.GetInt(InBlockXIdx), a_NBT.GetInt(InBlockYIdx), a_NBT.GetInt(InBlockZIdx))); + break; + } + case TAG_Short: + { + // Vanilla uses this + Arrow->SetBlockHit(Vector3i((int)a_NBT.GetShort(InBlockXIdx), (int)a_NBT.GetShort(InBlockYIdx), (int)a_NBT.GetShort(InBlockZIdx))); + break; + } + } + } } // Store the new arrow in the entities list: -- cgit v1.2.3 From 060ac500fcd369814d43100549e3d8b0ab51304d Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 19:19:30 +0200 Subject: Fixed wrong Surrounding size --- src/Mobs/Villager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 1cdac7c74..0efd5501e 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -109,11 +109,11 @@ void cVillager::HandleFarmerPrepareFarmCrops() Surrounding.Read( m_World, (int) GetPosX() - 5, - (int) GetPosX() + 5, + (int) GetPosX() + 6, (int) GetPosY() - 3, - (int) GetPosY() + 3, + (int) GetPosY() + 4, (int) GetPosZ() - 5, - (int) GetPosZ() + 5 + (int) GetPosZ() + 6 ); for (int I = 0; I < 5; I++) -- cgit v1.2.3 From 050b28741bbc503170679d5d3e91000f06f4d6ea Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 25 Sep 2014 19:28:11 +0200 Subject: Comment style --- src/Entities/HangingEntity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h index 455f2f23f..1cc0034e1 100644 --- a/src/Entities/HangingEntity.h +++ b/src/Entities/HangingEntity.h @@ -24,7 +24,7 @@ public: eBlockFace GetDirection() const { return m_BlockFace; } // tolua_export /** Set the orientation from the hanging entity */ - void SetDirection(eBlockFace a_BlockFace); // tolua_export + void SetDirection(eBlockFace a_BlockFace); // tolua_export /** Returns the X coord. */ int GetTileX() const { return POSX_TOINT; } // tolua_export -- cgit v1.2.3 From 3459bc1ede4ebbb8177444cc2b265ecea0678dea Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 19:42:35 +0200 Subject: Protocol 1.8: Added checks for values presence. Reported by @worktycho / Coverity. --- src/Protocol/Protocol18x.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 94eaa43db..c07441ef7 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1966,13 +1966,19 @@ void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) { UInt32 EncKeyLength, EncNonceLength; - a_ByteBuffer.ReadVarInt(EncKeyLength); + if (!a_ByteBuffer.ReadVarInt(EncKeyLength)) + { + return; + } AString EncKey; if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) { return; } - a_ByteBuffer.ReadVarInt(EncNonceLength); + if (!a_ByteBuffer.ReadVarInt(EncNonceLength)) + { + return; + } AString EncNonce; if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) { -- cgit v1.2.3 From 27187371ebe3988f92a03d5ed822aba5f3d97d79 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 20:34:49 +0200 Subject: Protocol 1.8: Handling packet compression properly. The compression didn't work with CommLog turned on. --- src/Protocol/Protocol18x.cpp | 47 +++++++++++++++++++++++++++++++++----------- src/Protocol/Protocol18x.h | 6 ++++-- 2 files changed, 39 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index c07441ef7..8a9c492ff 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1711,20 +1711,43 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) m_ReceivedData.ResetRead(); break; } - cByteBuffer bb(PacketLen + 1); - VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); - m_ReceivedData.CommitRead(); - - // Compressed packets + + // Check packet for compression: + UInt32 CompressedSize = 0; + AString UncompressedData; if (m_State == 3) { - UInt32 CompressedSize; - if (!bb.ReadVarInt(CompressedSize)) + UInt32 NumBytesRead = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadVarInt(CompressedSize); + if (CompressedSize > 0) { - // Not enough data - break; + // Decompress the data: + AString CompressedData; + m_ReceivedData.ReadString(CompressedData, CompressedSize); + InflateString(CompressedData.data(), CompressedSize, UncompressedData); + PacketLen = UncompressedData.size(); + } + else + { + NumBytesRead -= m_ReceivedData.GetReadableSpace(); // How many bytes has the CompressedSize taken up? + ASSERT(PacketLen > NumBytesRead); + PacketLen -= NumBytesRead; } } + + // Move the packet payload to a separate cByteBuffer, bb: + cByteBuffer bb(PacketLen + 1); + if (CompressedSize == 0) + { + // No compression was used, move directly + VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); + } + else + { + // Compression was used, move the uncompressed data: + VERIFY(bb.Write(UncompressedData.data(), UncompressedData.size())); + } + m_ReceivedData.CommitRead(); UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) @@ -2299,7 +2322,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - a_ByteBuffer.ReadAll(Data); + a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); m_Client->HandlePluginMessage(Channel, Data); } @@ -2526,7 +2549,7 @@ void cProtocol180::SendData(const char * a_Data, size_t a_Size) -bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes) +bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) { HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); if (ItemType == -1) @@ -2547,7 +2570,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a } AString Metadata; - if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_RemainingBytes) || (Metadata.size() == 0) || (Metadata[0] == 0)) + if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes - 1) || (Metadata.size() == 0) || (Metadata[0] == 0)) { // No metadata return true; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index eb0253663..df188b70f 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -321,8 +321,10 @@ protected: void SendCompass(const cWorld & a_World); - /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ - virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes = 0); + /** Reads an item out of the received data, sets a_Item to the values read. + Returns false if not enough received data. + a_KeepRemainingBytes tells the function to keep that many bytes at the end of the buffer. */ + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes = 0); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); -- cgit v1.2.3 From 8f4cc27e39188d302f6575e7324002e2515fd789 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 20:46:50 +0200 Subject: Added cByteBuffer::WriteBEUShort(). --- src/ByteBuffer.cpp | 13 +++++++++++++ src/ByteBuffer.h | 1 + src/Protocol/ChunkDataSerializer.cpp | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 17e8091c7..5bf98eda9 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -547,6 +547,19 @@ bool cByteBuffer::WriteBEShort(short a_Value) +bool cByteBuffer::WriteBEUShort(unsigned short a_Value) +{ + CHECK_THREAD; + CheckValid(); + PUTBYTES(2); + u_short Converted = htons((u_short)a_Value); + return WriteBuf(&Converted, 2); +} + + + + + bool cByteBuffer::WriteBEInt(int a_Value) { CHECK_THREAD; diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index c1c71d8c4..74dc378d4 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -82,6 +82,7 @@ public: bool WriteChar (char a_Value); bool WriteByte (unsigned char a_Value); bool WriteBEShort (short a_Value); + bool WriteBEUShort (unsigned short a_Value); bool WriteBEInt (int a_Value); bool WriteBEInt64 (Int64 a_Value); bool WriteBEFloat (float a_Value); diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index a133cc0e3..5d080656d 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -191,7 +191,7 @@ void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_Chu Packet.WriteBEInt(a_ChunkX); Packet.WriteBEInt(a_ChunkZ); Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag - Packet.WriteBEShort((short) 0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff + Packet.WriteBEUShort(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff // Write the chunk size: const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width; -- cgit v1.2.3 From e5293706de4433d5198e510de0a3e32f572ce230 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 20:47:16 +0200 Subject: TwoLevel BioGen: reads params from INI file. --- src/Generating/BioGen.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 217ca8f80..3ee0bd4c5 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -913,15 +913,32 @@ EMCSBiome cBioGenTwoLevel::SelectBiome(int a_BiomeGroup, int a_BiomeIdx, int a_D void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile) { - // TODO: Read these from a file - m_VoronoiLarge.SetCellSize(1024); - m_VoronoiSmall.SetCellSize(128); - m_DistortX.AddOctave(0.01f, 16); - m_DistortX.AddOctave(0.005f, 8); - m_DistortX.AddOctave(0.0025f, 4); - m_DistortZ.AddOctave(0.01f, 16); - m_DistortZ.AddOctave(0.005f, 8); - m_DistortZ.AddOctave(0.0025f, 4); + m_VoronoiLarge.SetCellSize(a_IniFile.GetValueSetI("Generator", "TwoLevelLargeCellSize", 1024)); + m_VoronoiSmall.SetCellSize(a_IniFile.GetValueSetI("Generator", "TwoLevelSmallCellSize", 128)); + m_DistortX.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Freq", 0.01), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Amp", 16) + ); + m_DistortX.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Freq", 0.005), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Amp", 8) + ); + m_DistortX.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Freq", 0.0025), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Amp", 4) + ); + m_DistortZ.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Freq", 0.01), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Amp", 16) + ); + m_DistortZ.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Freq", 0.005), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Amp", 8) + ); + m_DistortZ.AddOctave( + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Freq", 0.0025), + (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Amp", 4) + ); } -- cgit v1.2.3 From 0443f5d531b21917b3605254b17475569573fc48 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 21:23:05 +0200 Subject: cByteBuffer: Fixed position reading. --- src/ByteBuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 5bf98eda9..e61a90bbc 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -500,9 +500,9 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) UInt32 BlockXRaw = (Value >> 38) & 0x3ffffff; UInt32 BlockYRaw = (Value >> 26) & 0xfff; UInt32 BlockZRaw = (Value & 0x3ffffff); - a_BlockX = ((BlockXRaw & 0x2000000) == 0) ? BlockXRaw : (~(BlockXRaw & 0x1ffffff)) + 1; - a_BlockY = ((BlockYRaw & 0x800) == 0) ? BlockYRaw : (~(BlockXRaw & 0x7ff)) + 1; - a_BlockZ = ((BlockZRaw & 0x2000000) == 0) ? BlockZRaw : (~(BlockZRaw & 0x1ffffff)) + 1; + a_BlockX = ((BlockXRaw & 0x2000000) == 0) ? BlockXRaw : -(0x03ffffff - (int)BlockXRaw + 1); + a_BlockY = ((BlockYRaw & 0x800) == 0) ? BlockYRaw : -(0x07ff - (int)BlockYRaw + 1); + a_BlockZ = ((BlockZRaw & 0x2000000) == 0) ? BlockZRaw : -(0x03ffffff - (int)BlockZRaw + 1); return true; } -- cgit v1.2.3 From 976c6bd32bd81e26fed392a55dc25f2090f18735 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 21:33:20 +0200 Subject: Protocol 1.8: Fixed plugin message packet. --- src/Protocol/Protocol18x.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 3e1863f97..896947d03 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1000,6 +1000,7 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); + Pkt.WriteVarInt((UInt32)a_Message.size()); Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -2326,8 +2327,9 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); AString Data; - a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); + a_ByteBuffer.ReadString(Data, DataLen); m_Client->HandlePluginMessage(Channel, Data); } -- cgit v1.2.3 From 6b260f06ba8ec773e4a81fea38fb123b1ea09081 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 25 Sep 2014 23:06:21 +0200 Subject: cByteBuffer: Simplified ReadPosition(). Also, by popular demand, added more comments to the code. --- src/ByteBuffer.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index e61a90bbc..70fdc008c 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -497,12 +497,15 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ) return false; } - UInt32 BlockXRaw = (Value >> 38) & 0x3ffffff; - UInt32 BlockYRaw = (Value >> 26) & 0xfff; - UInt32 BlockZRaw = (Value & 0x3ffffff); - a_BlockX = ((BlockXRaw & 0x2000000) == 0) ? BlockXRaw : -(0x03ffffff - (int)BlockXRaw + 1); - a_BlockY = ((BlockYRaw & 0x800) == 0) ? BlockYRaw : -(0x07ff - (int)BlockYRaw + 1); - a_BlockZ = ((BlockZRaw & 0x2000000) == 0) ? BlockZRaw : -(0x03ffffff - (int)BlockZRaw + 1); + // Convert the 64 received bits into 3 coords: + UInt32 BlockXRaw = (Value >> 38) & 0x03ffffff; // Top 26 bits + UInt32 BlockYRaw = (Value >> 26) & 0x0fff; // Middle 12 bits + UInt32 BlockZRaw = (Value & 0x03ffffff); // Bottom 26 bits + + // If the highest bit in the number's range is set, convert the number into negative: + a_BlockX = ((BlockXRaw & 0x02000000) == 0) ? BlockXRaw : -(0x04000000 - (int)BlockXRaw); + a_BlockY = ((BlockYRaw & 0x0800) == 0) ? BlockYRaw : -(0x0800 - (int)BlockYRaw); + a_BlockZ = ((BlockZRaw & 0x02000000) == 0) ? BlockZRaw : -(0x04000000 - (int)BlockZRaw); return true; } -- cgit v1.2.3 From 157cad900724f26f7d2f19fae1d7e917510170d8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 26 Sep 2014 13:04:34 +0200 Subject: Improved searching for spawn. Won't spawn on a small island inside ocean anymore. --- src/World.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 8664bbec6..60d0ea723 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -681,8 +681,19 @@ void cWorld::GenerateRandomSpawn(void) { LOGD("Generating random spawnpoint..."); - while (IsBlockWaterOrIce(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ))) + // Look for a spawn point at most 100 chunks away from map center: + for (int i = 0; i < 100; i++) { + EMCSBiome biome = GetBiomeAt((int)m_SpawnX, (int)m_SpawnZ); + if ( + (biome != biOcean) && (biome != biFrozenOcean) && // The biome is acceptable (don't want a small ocean island) + !IsBlockWaterOrIce(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ)) // The terrain is acceptable (don't want to spawn inside a lake / river) + ) + { + // A good spawnpoint was found + break; + } + // Try a neighboring chunk: if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords { m_SpawnX += cChunkDef::Width; @@ -691,11 +702,11 @@ void cWorld::GenerateRandomSpawn(void) { m_SpawnZ += cChunkDef::Width; } - } + } // for i - 100* m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // 1.6f to accomodate player height - LOGD("Generated random spawnpoint %i %i %i", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ); + LOGINFO("Generated random spawnpoint position {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ); } -- cgit v1.2.3 From 749c6092d3bff2cf6c22b6b3299d6883b070b08a Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 26 Sep 2014 14:31:52 +0200 Subject: Added type checking to map loading. --- src/WorldStorage/MapSerializer.cpp | 18 +++++++++--------- src/WorldStorage/MapSerializer.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 012fc52f3..4a913c81a 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -130,14 +130,14 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) } int CurrLine = a_NBT.FindChildByName(Data, "scale"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { - unsigned int Scale = a_NBT.GetByte(CurrLine); + unsigned int Scale = (unsigned int)a_NBT.GetByte(CurrLine); m_Map->SetScale(Scale); } CurrLine = a_NBT.FindChildByName(Data, "dimension"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); @@ -149,9 +149,9 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) } CurrLine = a_NBT.FindChildByName(Data, "width"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Short)) { - unsigned int Width = a_NBT.GetShort(CurrLine); + unsigned int Width = (unsigned int)a_NBT.GetShort(CurrLine); if (Width != 128) { return false; @@ -160,9 +160,9 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) } CurrLine = a_NBT.FindChildByName(Data, "height"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Short)) { - unsigned int Height = a_NBT.GetShort(CurrLine); + unsigned int Height = (unsigned int)a_NBT.GetShort(CurrLine); if (Height >= 256) { return false; @@ -171,14 +171,14 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) } CurrLine = a_NBT.FindChildByName(Data, "xCenter"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { int CenterX = a_NBT.GetInt(CurrLine); m_Map->m_CenterX = CenterX; } CurrLine = a_NBT.FindChildByName(Data, "zCenter"); - if (CurrLine >= 0) + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Int)) { int CenterZ = a_NBT.GetInt(CurrLine); m_Map->m_CenterZ = CenterZ; diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index 4fa40f6f9..e13a75c8f 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -28,10 +28,10 @@ public: cMapSerializer(const AString& a_WorldName, cMap * a_Map); - /** Try to load the scoreboard */ + /** Try to load the map */ bool Load(void); - /** Try to save the scoreboard */ + /** Try to save the map */ bool Save(void); -- cgit v1.2.3 From 6ffb7835e7903bb97d747a80d25c8c72887ea11a Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 26 Sep 2014 16:26:03 +0100 Subject: Removed a few unnessicary includes --- src/Bindings/DeprecatedBindings.cpp | 5 ----- src/Bindings/LuaChunkStay.cpp | 1 - src/Bindings/LuaChunkStay.h | 1 + src/Bindings/LuaState.h | 1 - src/Bindings/LuaWindow.cpp | 1 - src/Bindings/ManualBindings.cpp | 2 -- src/Bindings/Plugin.h | 14 +++++++++----- src/Bindings/PluginLua.cpp | 4 +++- src/Bindings/PluginManager.cpp | 2 -- src/Bindings/PluginManager.h | 6 +++--- 10 files changed, 16 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 36243bc92..02aa15be4 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -5,11 +5,6 @@ #undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" -#include "Plugin.h" -#include "PluginLua.h" -#include "PluginManager.h" -#include "LuaWindow.h" -#include "LuaChunkStay.h" #include "../BlockInfo.h" diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 154bcb200..a3d3a8090 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -6,7 +6,6 @@ #include "Globals.h" #include "LuaChunkStay.h" #include "PluginLua.h" -#include "../World.h" diff --git a/src/Bindings/LuaChunkStay.h b/src/Bindings/LuaChunkStay.h index 49ab9a0ad..d76b67de9 100644 --- a/src/Bindings/LuaChunkStay.h +++ b/src/Bindings/LuaChunkStay.h @@ -18,6 +18,7 @@ // fwd: class cPluginLua; +class cChunkMap; diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 44f187701..094a200e0 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -56,7 +56,6 @@ struct HTTPRequest; class cWebAdmin; struct HTTPTemplateRequest; class cTNTEntity; -class cCreeper; class cHopperEntity; class cBlockEntity; class cBoundingBox; diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index 1a2582ab0..c4d03b86b 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -6,7 +6,6 @@ #include "LuaWindow.h" #include "../UI/SlotArea.h" #include "PluginLua.h" -#include "../Entities/Player.h" #include "lua/src/lauxlib.h" // Needed for LUA_REFNIL diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index b7ea65759..d8134f159 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -5,7 +5,6 @@ #undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "polarssl/md5.h" -#include "Plugin.h" #include "PluginLua.h" #include "PluginManager.h" #include "LuaWindow.h" @@ -27,7 +26,6 @@ #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" #include "../LineBlockTracer.h" -#include "../Protocol/Authenticator.h" #include "../WorldStorage/SchematicFileSerializer.h" #include "../CompositeChat.h" diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index c9a53346d..9c10a1d56 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -1,23 +1,27 @@ #pragma once -#include "PluginManager.h" +//#include "PluginManager.h" +#include "Defines.h" +class cCommandOutputCallback; +class cItems; +class cHopperEntity; +class cBlockEntityWithItems; class cClientHandle; -class cPlayer; class cPickup; -class cItem; +class cPlayer; +class cProjectileEntity; class cEntity; +class cMonster; class cWorld; class cChunkDesc; struct TakeDamageInfo; -// fwd: cPlayer.h -class cPlayer; // fwd: CraftingRecipes.h class cCraftingGrid; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 2c2d05547..2629eb641 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -12,10 +12,12 @@ #endif #include "PluginLua.h" #include "../CommandOutput.h" +#include "PluginManager.h" +#include "../Item.h" extern "C" { - #include "lua/src/lualib.h" + #include "lua/src/lauxlib.h" } #undef TOLUA_TEMPLATE_BIND diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index f62e6ae02..e0faa838a 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -4,12 +4,10 @@ #include "PluginManager.h" #include "Plugin.h" #include "PluginLua.h" -#include "../WebAdmin.h" #include "../Item.h" #include "../Root.h" #include "../Server.h" #include "../CommandOutput.h" -#include "../ChatColor.h" #include "inifile/iniFile.h" #include "../Entities/Player.h" diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index cef6619d7..fff3bc323 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -1,9 +1,8 @@ #pragma once -#include "../Item.h" - +#include "Defines.h" @@ -36,7 +35,6 @@ class cPickup; // fwd: Pawn.h struct TakeDamageInfo; -class cPawn; // fwd: CommandOutput.h class cCommandOutputCallback; @@ -49,6 +47,8 @@ class cBlockEntityWithItems; +class cItems; + // tolua_begin -- cgit v1.2.3 From d83d6456e8aedf84dcda89eb29d20d8ba834748e Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 26 Sep 2014 17:37:19 +0200 Subject: Fixed players custom name in 1.8 --- src/ClientHandle.cpp | 4 ++-- src/ClientHandle.h | 2 +- src/Entities/Player.cpp | 7 ++++--- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 22 ++++------------------ src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol17x.cpp | 20 ++++---------------- src/Protocol/Protocol17x.h | 2 +- src/Protocol/Protocol18x.cpp | 21 +++++---------------- src/Protocol/Protocol18x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 4 ++-- src/World.h | 2 +- 14 files changed, 30 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 1e2f4ffad..878d309c9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2453,9 +2453,9 @@ void cClientHandle::SendPlayerListUpdatePing(const cPlayer & a_Player) -void cClientHandle::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +void cClientHandle::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { - m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); + m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index b91c3722c..0a936a2ca 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -172,7 +172,7 @@ public: void SendPlayerListRemovePlayer (const cPlayer & a_Player); void SendPlayerListUpdateGameMode (const cPlayer & a_Player); void SendPlayerListUpdatePing (const cPlayer & a_Player); - void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName); + void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 1bdb752c5..6875506ea 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -816,7 +816,8 @@ void cPlayer::SetCustomName(const AString & a_CustomName) { return; } - AString OldCustomName = m_CustomName; + + m_World->BroadcastPlayerListRemovePlayer(*this); m_CustomName = a_CustomName; if (m_CustomName.length() > 16) @@ -824,8 +825,8 @@ void cPlayer::SetCustomName(const AString & a_CustomName) m_CustomName = m_CustomName.substr(0, 16); } - m_World->BroadcastPlayerListUpdateDisplayName(*this, m_CustomName); - m_World->BroadcastSpawnEntity(*this, m_ClientHandle); + m_World->BroadcastPlayerListAddPlayer(*this); + m_World->BroadcastSpawnEntity(*this, GetClientHandle()); } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index f351ee4b9..b2ee92918 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -98,7 +98,7 @@ public: virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) = 0; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0; virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) = 0; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) = 0; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) = 0; virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index ba4cfa7ef..8a5f26c8b 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -767,25 +767,11 @@ void cProtocol125::SendPlayerListUpdatePing(const cPlayer & a_Player) -void cProtocol125::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +void cProtocol125::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { - if (a_OldListName == a_Player.GetPlayerListName()) - { - return; - } - - cCSLock Lock(m_CSPacket); - - // Remove the old name from the tablist: - { - WriteByte (PACKET_PLAYER_LIST_ITEM); - WriteString(a_OldListName); - WriteBool (false); - WriteShort (0); - Flush(); - } - - SendPlayerListAddPlayer(a_Player); + // Not implemented in this protocol version + UNUSED(a_Player); + UNUSED(a_CustomName); } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 4241c1fd4..3ea116c3b 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -69,7 +69,7 @@ public: virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 73d2a74f9..ce4732471 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -838,23 +838,11 @@ void cProtocol172::SendPlayerListUpdatePing(const cPlayer & a_Player) -void cProtocol172::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +void cProtocol172::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { - ASSERT(m_State == 3); // In game mode? - if (a_OldListName == a_Player.GetPlayerListName()) - { - return; - } - - // Remove the old name from the tablist: - { - cPacketizer Pkt(*this, 0x38); - Pkt.WriteString(a_OldListName); - Pkt.WriteBool(false); - Pkt.WriteShort(0); - } - - SendPlayerListAddPlayer(a_Player); + // Not implemented in this protocol version + UNUSED(a_Player); + UNUSED(a_CustomName); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 7ec7d0fce..8f537f5d7 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -105,7 +105,7 @@ public: virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 896947d03..2ee50bb4a 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -802,7 +802,7 @@ void cProtocol180::SendPlayerListAddPlayer(const cPlayer & a_Player) Pkt.WriteVarInt(0); Pkt.WriteVarInt(1); Pkt.WriteUUID(a_Player.GetUUID()); - Pkt.WriteString(a_Player.GetName()); + Pkt.WriteString(a_Player.GetPlayerListName()); const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); Pkt.WriteVarInt(Properties.size()); @@ -824,17 +824,7 @@ void cProtocol180::SendPlayerListAddPlayer(const cPlayer & a_Player) Pkt.WriteVarInt((UInt32)a_Player.GetGameMode()); Pkt.WriteVarInt((UInt32)a_Player.GetClientHandle()->GetPing()); - - AString CustomName = a_Player.GetPlayerListName(); - if (CustomName != a_Player.GetName()) - { - Pkt.WriteBool(true); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", CustomName.c_str())); - } - else - { - Pkt.WriteBool(false); - } + Pkt.WriteBool(false); } @@ -885,7 +875,7 @@ void cProtocol180::SendPlayerListUpdatePing(const cPlayer & a_Player) -void cProtocol180::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +void cProtocol180::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { ASSERT(m_State == 3); // In game mode? @@ -894,15 +884,14 @@ void cProtocol180::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, con Pkt.WriteVarInt(1); Pkt.WriteUUID(a_Player.GetUUID()); - AString CustomName = a_Player.GetPlayerListName(); - if (CustomName == a_Player.GetName()) + if (a_CustomName.empty()) { Pkt.WriteBool(false); } else { Pkt.WriteBool(true); - Pkt.WriteString(Printf("{\"text\":\"%s\"}", CustomName.c_str())); + Pkt.WriteString(Printf("{\"text\":\"%s\"}", a_CustomName.c_str())); } } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index df188b70f..554edecc8 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -101,7 +101,7 @@ public: virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index a5b745c2f..fe53aede1 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -529,10 +529,10 @@ void cProtocolRecognizer::SendPlayerListUpdatePing(const cPlayer & a_Player) -void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) +void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) { ASSERT(m_Protocol != NULL); - m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); + m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 55348a758..e4419f6ae 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -105,7 +105,7 @@ public: virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName) override; + virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/World.cpp b/src/World.cpp index 60d0ea723..1f3894978 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2236,7 +2236,7 @@ void cWorld::BroadcastPlayerListUpdatePing(const cPlayer & a_Player, const cClie -void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName, const cClientHandle * a_Exclude) +void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2246,7 +2246,7 @@ void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, cons { continue; } - ch->SendPlayerListUpdateDisplayName(a_Player, a_OldListName); + ch->SendPlayerListUpdateDisplayName(a_Player, a_CustomName); } } diff --git a/src/World.h b/src/World.h index eee0ced54..76c1d148d 100644 --- a/src/World.h +++ b/src/World.h @@ -244,7 +244,7 @@ public: void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_OldListName, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); -- cgit v1.2.3 From ad5d0eda9c35a7f4a00e11743f545d057d188a8c Mon Sep 17 00:00:00 2001 From: tycho Date: Fri, 26 Sep 2014 17:00:34 +0100 Subject: Fixed issue with casting --- src/Chunk.cpp | 3 +++ src/Chunk.h | 4 ++-- src/Simulator/RedstoneSimulator.h | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a7dec3fe3..06260bead 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -91,6 +91,7 @@ cChunk::cChunk( m_NeighborZP(a_NeighborZP), m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()), m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()), + m_RedstoneSimulatorData(NULL), m_AlwaysTicked(0) { if (a_NeighborXM != NULL) @@ -159,6 +160,8 @@ cChunk::~cChunk() m_WaterSimulatorData = NULL; delete m_LavaSimulatorData; m_LavaSimulatorData = NULL; + delete m_RedstoneSimulatorData; + m_RedstoneSimulatorData = NULL; } diff --git a/src/Chunk.h b/src/Chunk.h index a3de730dc..7a2e75685 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -416,7 +416,7 @@ public: cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; } cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; } - cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; } + cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return m_RedstoneSimulatorData; } bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; } void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; } @@ -501,7 +501,7 @@ private: cFluidSimulatorData * m_LavaSimulatorData; cSandSimulatorChunkData m_SandSimulatorData; - cRedstoneSimulatorChunkData m_RedstoneSimulatorData; + cRedstoneSimulatorChunkData * m_RedstoneSimulatorData; /** Indicates if simulate-once blocks should be updated by the redstone simulator */ diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 0e3dd495d..f6d36f869 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -7,10 +7,12 @@ class cRedstoneSimulatorChunkData { public: - virtual ~cRedstoneSimulatorChunkData() {} + virtual ~cRedstoneSimulatorChunkData() = 0; } ; +inline cRedstoneSimulatorChunkData::~cRedstoneSimulatorChunkData() {} + template class cRedstoneSimulator : public cSimulator -- cgit v1.2.3 From a3f940f47c8981146feed66225c1dd8066bac0e2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 26 Sep 2014 18:13:19 +0100 Subject: Removed more unessicary includes --- src/Bindings/WebPlugin.cpp | 1 - src/Bindings/WebPlugin.h | 1 - src/BlockEntities/BlockEntity.h | 5 ++--- src/BlockEntities/BlockEntityWithItems.h | 1 + src/BlockEntities/ChestEntity.cpp | 1 - src/BlockEntities/ChestEntity.h | 2 -- src/BlockEntities/CommandBlockEntity.cpp | 6 ++---- src/BlockEntities/DispenserEntity.cpp | 3 --- src/BlockEntities/DropSpenserEntity.cpp | 1 - src/BlockEntities/DropSpenserEntity.h | 1 - src/BlockEntities/DropperEntity.cpp | 2 -- src/BlockEntities/EnderChestEntity.cpp | 1 - src/BlockEntities/EnderChestEntity.h | 1 - src/BlockEntities/FlowerPotEntity.cpp | 1 - src/BlockEntities/FlowerPotEntity.h | 2 +- src/BlockEntities/FurnaceEntity.cpp | 2 -- src/BlockEntities/FurnaceEntity.h | 1 - src/BlockEntities/HopperEntity.cpp | 3 --- src/BlockEntities/JukeboxEntity.cpp | 4 ++-- src/BlockEntities/JukeboxEntity.h | 1 - src/BlockEntities/MobHeadEntity.cpp | 1 - src/BlockEntities/MobHeadEntity.h | 2 +- src/BlockEntities/NoteEntity.cpp | 2 +- src/BlockEntities/SignEntity.cpp | 4 ++-- src/Blocks/BlockBed.cpp | 9 +++++++++ src/Blocks/BlockBed.h | 8 +++++--- src/Blocks/BlockBigFlower.h | 2 +- src/Blocks/BlockDirt.h | 4 ++-- src/Blocks/BlockDoor.cpp | 1 - src/Blocks/BlockDoor.h | 1 + src/Blocks/BlockHandler.cpp | 4 ++-- src/Blocks/BlockHandler.h | 8 ++++---- src/Blocks/BlockPiston.cpp | 1 + src/Blocks/BlockRedstoneRepeater.h | 2 +- src/Blocks/BlockSlab.h | 1 + src/Blocks/BlockVine.h | 2 +- src/Blocks/ChunkInterface.cpp | 1 + src/Blocks/ChunkInterface.h | 3 ++- src/Chunk.cpp | 1 + src/Chunk.h | 6 +++++- src/ChunkMap.cpp | 2 +- src/ChunkSender.cpp | 1 + src/Entities/ArrowEntity.cpp | 1 - src/Entities/EnderCrystal.cpp | 2 +- src/Entities/Entity.cpp | 1 - src/Items/ItemBucket.h | 1 + src/Mobs/Villager.h | 2 +- src/Simulator/FloodyFluidSimulator.cpp | 1 + 48 files changed, 55 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index 4fa64d937..eca1c74e6 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -3,7 +3,6 @@ #include "WebPlugin.h" #include "../WebAdmin.h" -#include "../Server.h" #include "../Root.h" diff --git a/src/Bindings/WebPlugin.h b/src/Bindings/WebPlugin.h index 46bc0cd2d..9b825b918 100644 --- a/src/Bindings/WebPlugin.h +++ b/src/Bindings/WebPlugin.h @@ -1,7 +1,6 @@ #pragma once -struct lua_State; struct HTTPRequest; diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 5710f8543..066bbc696 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -1,8 +1,6 @@ #pragma once -#include "../ClientHandle.h" -#include "../World.h" @@ -13,8 +11,9 @@ namespace Json class Value; }; +class cChunk; class cPlayer; -class cPacket; +class cWorld; diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index 5f1639d45..e511ee8cb 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -12,6 +12,7 @@ #include "BlockEntity.h" #include "../ItemGrid.h" #include "../UI/WindowOwner.h" +#include "World.h" diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index 21e1f6ba2..5447c7c49 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -5,7 +5,6 @@ #include "../Item.h" #include "../Entities/Player.h" #include "../UI/Window.h" -#include "json/json.h" diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index cd06b3e2c..fa36e08be 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -13,8 +13,6 @@ namespace Json }; class cClientHandle; -class cServer; -class cNBTData; diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 20702a9ac..318874a9b 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -4,16 +4,14 @@ // Implements the cCommandBlockEntity class representing a single command block in the world #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "json/json.h" #include "CommandBlockEntity.h" -#include "../Entities/Player.h" -#include "../WorldStorage/FastNBT.h" #include "../CommandOutput.h" #include "../Root.h" #include "../Server.h" // ExecuteConsoleCommand() -#include "../Chunk.h" #include "../ChatColor.h" +#include "../World.h" +#include "../ClientHandle.h" diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 068891d66..4794375cf 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -2,13 +2,10 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "DispenserEntity.h" -#include "../Entities/Player.h" #include "../Simulator/FluidSimulator.h" #include "../Chunk.h" #include "../World.h" -#include "../Entities/ArrowEntity.h" -#include "../Entities/FireChargeEntity.h" #include "../Entities/ProjectileEntity.h" diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index dc38e3e9b..260c71641 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -8,7 +8,6 @@ #include "DropSpenserEntity.h" #include "../Entities/Player.h" #include "../Chunk.h" -#include "json/json.h" diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index be56447aa..c70cd0531 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -22,7 +22,6 @@ namespace Json } class cClientHandle; -class cServer; diff --git a/src/BlockEntities/DropperEntity.cpp b/src/BlockEntities/DropperEntity.cpp index 5d4a8ad97..5cbf6d56e 100644 --- a/src/BlockEntities/DropperEntity.cpp +++ b/src/BlockEntities/DropperEntity.cpp @@ -5,8 +5,6 @@ #include "Globals.h" #include "DropperEntity.h" -#include "../Entities/Player.h" -#include "../Simulator/FluidSimulator.h" diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index 17816d63e..b870f9e50 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -5,7 +5,6 @@ #include "../Item.h" #include "../Entities/Player.h" #include "../UI/Window.h" -#include "json/json.h" diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index ed178f6fc..311af8d76 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -3,7 +3,6 @@ #include "BlockEntity.h" #include "UI/WindowOwner.h" -#include "json/json.h" diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index e001634b8..d2bc59d34 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -4,7 +4,6 @@ // Implements the cFlowerPotEntity class representing a single flower pot in the world #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "json/json.h" #include "FlowerPotEntity.h" #include "../Entities/Player.h" #include "../Item.h" diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index 89901cf2d..b86f9c840 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -9,8 +9,8 @@ #pragma once #include "BlockEntity.h" +#include "Item.h" -class cItem; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index 72fd7f2b3..d7b2fd910 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -5,8 +5,6 @@ #include "../UI/Window.h" #include "../Entities/Player.h" #include "../Root.h" -#include "../Chunk.h" -#include "json/json.h" diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index cf1a755e0..7ac25cf52 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -14,7 +14,6 @@ namespace Json } class cClientHandle; -class cServer; diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 88e7b8e1b..444378c92 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -10,10 +10,7 @@ #include "../Entities/Pickup.h" #include "../Bindings/PluginManager.h" #include "ChestEntity.h" -#include "DropSpenserEntity.h" #include "FurnaceEntity.h" -#include "../BoundingBox.h" -#include "json/json.h" diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp index c96253b11..1131b99b0 100644 --- a/src/BlockEntities/JukeboxEntity.cpp +++ b/src/BlockEntities/JukeboxEntity.cpp @@ -3,8 +3,8 @@ #include "JukeboxEntity.h" #include "../World.h" -#include "json/json.h" - +#include "json/value.h" +#include "Entities/Player.h" diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index d677d340f..a6fdf3c7e 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -2,7 +2,6 @@ #pragma once #include "BlockEntity.h" -#include "../Entities/Player.h" diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp index ce895eb6f..9a1a40abe 100644 --- a/src/BlockEntities/MobHeadEntity.cpp +++ b/src/BlockEntities/MobHeadEntity.cpp @@ -4,7 +4,6 @@ // Implements the cMobHeadEntity class representing a single skull/head in the world #include "Globals.h" -#include "json/json.h" #include "MobHeadEntity.h" #include "../Entities/Player.h" diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index f91a3cc9e..45fa0d951 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -9,7 +9,7 @@ #pragma once #include "BlockEntity.h" - +#include "Defines.h" diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp index 95145c117..ecbedbcb1 100644 --- a/src/BlockEntities/NoteEntity.cpp +++ b/src/BlockEntities/NoteEntity.cpp @@ -3,7 +3,7 @@ #include "NoteEntity.h" #include "../World.h" -#include "json/json.h" +#include "json/value.h" diff --git a/src/BlockEntities/SignEntity.cpp b/src/BlockEntities/SignEntity.cpp index 23d9ef926..423d254d2 100644 --- a/src/BlockEntities/SignEntity.cpp +++ b/src/BlockEntities/SignEntity.cpp @@ -4,9 +4,9 @@ // Implements the cSignEntity class representing a single sign in the world #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules -#include "json/json.h" +#include "json/value.h" #include "SignEntity.h" -#include "../Entities/Player.h" +#include "../ClientHandle.h" diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index cd1cc2a5f..3b6328b38 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -4,6 +4,15 @@ +#include "BroadcastInterface.h" +#include "ChunkInterface.h" +#include "Entities/../World.h" +#include "Entities/Player.h" +#include "WorldInterface.h" + + + + void cBlockBedHandler::OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index bf9d9c01d..9fd45644b 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -2,12 +2,14 @@ #pragma once #include "BlockHandler.h" -#include "ChunkInterface.h" -#include "WorldInterface.h" #include "MetaRotator.h" -#include "../Entities/Player.h" +#include "Item.h" +class cChunkInterface; +class cPlayer; +class cWorldInterface; + diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 89ffc864d..3577bdd40 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" - +#include "ChunkInterface.h" diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 23e5a3cde..60d81db72 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -3,8 +3,8 @@ #include "BlockHandler.h" #include "../FastRandom.h" - - +#include "Root.h" +#include "Bindings/PluginManager.h" diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 1a277f071..96345a2df 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -1,7 +1,6 @@ #include "Globals.h" #include "BlockDoor.h" -#include "../Item.h" #include "../Entities/Player.h" diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 69e30d9c8..b2f9e4dcd 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -5,6 +5,7 @@ #include "../Entities/Player.h" #include "Chunk.h" #include "MetaRotator.h" +#include "ChunkInterface.h" diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 30b303cfd..3e7de123c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -3,8 +3,6 @@ #include "BlockHandler.h" #include "../Item.h" #include "../World.h" -#include "../Root.h" -#include "../Bindings/PluginManager.h" #include "../Chunk.h" #include "BlockAnvil.h" #include "BlockBed.h" @@ -84,6 +82,8 @@ #include "BlockWorkbench.h" +#include "BlockPluginInterface.h" + diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 3a8115da0..83de836cb 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -2,10 +2,6 @@ #pragma once #include "../Defines.h" -#include "../Item.h" -#include "WorldInterface.h" -#include "ChunkInterface.h" -#include "BlockPluginInterface.h" @@ -14,6 +10,10 @@ // fwd: class cPlayer; class cChunk; +class cBlockPluginInterface; +class cChunkInterface; +class cWorldInterface; +class cItems; diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 0169fb266..34d11f675 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -5,6 +5,7 @@ #include "../World.h" #include "../Entities/Player.h" #include "BlockInServerPluginInterface.h" +#include "ChunkInterface.h" diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 3e5259c56..1eb67f714 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -4,7 +4,7 @@ #include "BlockHandler.h" #include "Chunk.h" #include "MetaRotator.h" - +#include "ChunkInterface.h" diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 0ad30bb2b..fb92db8fe 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -12,6 +12,7 @@ #include "BlockHandler.h" #include "../Items/ItemHandler.h" #include "Root.h" +#include "ChunkInterface.h" diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index b61673cc5..06d84f2d4 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -2,7 +2,7 @@ #include "BlockHandler.h" #include "MetaRotator.h" - +#include "Bindings/PluginManager.h" diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index 5ac4dcf80..e22a1410e 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -4,6 +4,7 @@ #include "ChunkInterface.h" #include "ChunkMap.h" #include "BlockHandler.h" +#include "WorldInterface.h" diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index 51647dc04..2f0cfea11 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -2,11 +2,12 @@ #pragma once #include "../ForEachChunkProvider.h" -#include "WorldInterface.h" class cChunkMap; +class cWorldInterface; +class cPlayer; class cChunkInterface: public cForEachChunkProvider diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a7dec3fe3..74e18de17 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -38,6 +38,7 @@ #include "BlockInServerPluginInterface.h" #include "SetChunkData.h" #include "BoundingBox.h" +#include "Blocks/ChunkInterface.h" #include "json/json.h" diff --git a/src/Chunk.h b/src/Chunk.h index a3de730dc..1d62ff73f 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -11,7 +11,7 @@ #include "Blocks/GetHandlerCompileTimeTemplate.h" - +#include "ChunkMap.h" @@ -31,7 +31,10 @@ class MTRand; class cPlayer; class cChunkMap; class cBeaconEntity; +class cBoundingBox; class cChestEntity; +class cCHunkDataCallback; +class cCommandBlockEntity; class cDispenserEntity; class cFurnaceEntity; class cNoteEntity; @@ -46,6 +49,7 @@ class cFluidSimulatorData; class cMobCensus; class cMobSpawner; class cRedstonePoweredEntity; +class cSetChunkData; typedef std::list cClientHandleList; typedef cItemCallback cEntityCallback; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 828d8f164..38a7d9bd4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -17,7 +17,7 @@ #include "MobSpawner.h" #include "BoundingBox.h" #include "SetChunkData.h" - +#include "Blocks/ChunkInterface.h" #include "Entities/Pickup.h" #ifndef _WIN32 diff --git a/src/ChunkSender.cpp b/src/ChunkSender.cpp index 95c4d03d2..a3151eb3f 100644 --- a/src/ChunkSender.cpp +++ b/src/ChunkSender.cpp @@ -12,6 +12,7 @@ #include "World.h" #include "BlockEntities/BlockEntity.h" #include "Protocol/ChunkDataSerializer.h" +#include "ClientHandle.h" diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 954e0a267..c265c5043 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -3,7 +3,6 @@ #include "Player.h" #include "ArrowEntity.h" #include "../Chunk.h" -#include "FastRandom.h" diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp index c17bb608e..30df2c110 100644 --- a/src/Entities/EnderCrystal.cpp +++ b/src/Entities/EnderCrystal.cpp @@ -3,8 +3,8 @@ #include "EnderCrystal.h" #include "ClientHandle.h" -#include "Player.h" #include "../Chunk.h" +#include "../World.h" diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index c733d60ad..da85dec50 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -3,7 +3,6 @@ #include "Entity.h" #include "../World.h" -#include "../Server.h" #include "../Root.h" #include "../Matrix4.h" #include "../ClientHandle.h" diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index a17c4838b..3a533958f 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -7,6 +7,7 @@ #include "../Blocks/BlockHandler.h" #include "../LineBlockTracer.h" #include "../BlockInServerPluginInterface.h" +#include "../Blocks/ChunkInterface.h" diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index aa81f0790..d3a38dbf0 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -2,7 +2,7 @@ #pragma once #include "PassiveMonster.h" - +#include "Blocks/ChunkInterface.h" diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 2c5c4b658..b839aa746 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -12,6 +12,7 @@ #include "../BlockArea.h" #include "../Blocks/BlockHandler.h" #include "../BlockInServerPluginInterface.h" +#include "../Blocks/ChunkInterface.h" -- cgit v1.2.3 From 4105be0bec76a7643c6527de46411f980a0a9e50 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Fri, 26 Sep 2014 19:44:06 +0200 Subject: Re-added 1.8 blocks to the redstone simulator --- src/Simulator/IncrementalRedstoneSimulator.inc | 55 +++++++++++++++++++++----- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index 3fa973463..6fda9824c 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -220,25 +220,36 @@ private: { switch (Block) { + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_ACACIA_FENCE_GATE: case E_BLOCK_ACTIVATOR_RAIL: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_BIRCH_FENCE_GATE: case E_BLOCK_COMMAND_BLOCK: - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_DARK_OAK_FENCE_GATE: case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: case E_BLOCK_FENCE_GATE: case E_BLOCK_HOPPER: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_IRON_TRAPDOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_JUNGLE_FENCE_GATE: case E_BLOCK_NOTE_BLOCK: - case E_BLOCK_TNT: - case E_BLOCK_TRAPDOOR: + case E_BLOCK_PISTON: + case E_BLOCK_POWERED_RAIL: case E_BLOCK_REDSTONE_LAMP_OFF: case E_BLOCK_REDSTONE_LAMP_ON: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: case E_BLOCK_REDSTONE_REPEATER_OFF: case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_POWERED_RAIL: case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_SPRUCE_FENCE_GATE: + case E_BLOCK_STICKY_PISTON: + case E_BLOCK_TNT: + case E_BLOCK_TRAPDOOR: + case E_BLOCK_WOODEN_DOOR: { return true; } @@ -279,19 +290,28 @@ private: switch (Block) { // All redstone devices, please alpha sort + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_ACACIA_FENCE_GATE: case E_BLOCK_ACTIVATOR_RAIL: case E_BLOCK_ACTIVE_COMPARATOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_BIRCH_FENCE_GATE: case E_BLOCK_BLOCK_OF_REDSTONE: case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_DARK_OAK_FENCE_GATE: + case E_BLOCK_DAYLIGHT_SENSOR: case E_BLOCK_DETECTOR_RAIL: case E_BLOCK_DISPENSER: - case E_BLOCK_DAYLIGHT_SENSOR: case E_BLOCK_DROPPER: case E_BLOCK_FENCE_GATE: case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: case E_BLOCK_HOPPER: case E_BLOCK_INACTIVE_COMPARATOR: case E_BLOCK_IRON_DOOR: + case E_BLOCK_IRON_TRAPDOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_JUNGLE_FENCE_GATE: case E_BLOCK_LEVER: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: case E_BLOCK_NOTE_BLOCK: @@ -303,6 +323,8 @@ private: case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: case E_BLOCK_REDSTONE_WIRE: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_SPRUCE_FENCE_GATE: case E_BLOCK_STICKY_PISTON: case E_BLOCK_STONE_BUTTON: case E_BLOCK_STONE_PRESSURE_PLATE: @@ -595,8 +617,8 @@ void cIncrementalRedstoneSimulatorx, dataitr->y, dataitr->z); break; case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_IRON_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_TRAPPED_CHEST: HandleTrappedChest(dataitr->x, dataitr->y, dataitr->z); break; @@ -607,12 +629,27 @@ void cIncrementalRedstoneSimulatorx, dataitr->y, dataitr->z, dataitr->Data); break; } + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_SPRUCE_DOOR: case E_BLOCK_WOODEN_DOOR: case E_BLOCK_IRON_DOOR: { HandleDoor(dataitr->x, dataitr->y, dataitr->z); break; } + case E_BLOCK_ACACIA_FENCE_GATE: + case E_BLOCK_BIRCH_FENCE_GATE: + case E_BLOCK_DARK_OAK_FENCE_GATE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_JUNGLE_FENCE_GATE: + case E_BLOCK_SPRUCE_FENCE_GATE: + { + HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); + break; + } case E_BLOCK_REDSTONE_LAMP_OFF: case E_BLOCK_REDSTONE_LAMP_ON: { -- cgit v1.2.3 From 9106a8c29bb07e73e223336e49ee9f3f1366b01a Mon Sep 17 00:00:00 2001 From: Masy98 Date: Fri, 26 Sep 2014 19:45:03 +0200 Subject: Moved curly brace to seperate line --- src/Items/ItemDoor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h index 402cef6c6..cd5baf44f 100644 --- a/src/Items/ItemDoor.h +++ b/src/Items/ItemDoor.h @@ -30,7 +30,8 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - switch (m_ItemType) { + switch (m_ItemType) + { case E_ITEM_WOODEN_DOOR: a_BlockType = E_BLOCK_WOODEN_DOOR; break; case E_ITEM_IRON_DOOR: a_BlockType = E_BLOCK_IRON_DOOR; break; case E_ITEM_SPRUCE_DOOR: a_BlockType = E_BLOCK_SPRUCE_DOOR; break; -- cgit v1.2.3 From 02db79d7251adb95ae84971674e68b9a2ff703ab Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 26 Sep 2014 19:00:26 +0100 Subject: Update Plugin.h --- src/Bindings/Plugin.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 9c10a1d56..fb22dd33e 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -1,8 +1,6 @@ #pragma once -//#include "PluginManager.h" - #include "Defines.h" class cCommandOutputCallback; -- cgit v1.2.3 From 0d83477540d9eb62c7a4f22f1f5f2b8cd79363ac Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 26 Sep 2014 22:53:11 +0200 Subject: Fixed UNUSED macro so that it doesn't require type knowledge. Introduced new UNUSED_VAR macro that is used when type knowledge is available (for local variables). --- src/Globals.h | 11 ++++++++++- src/WorldStorage/FastNBT.h | 8 ++++---- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Globals.h b/src/Globals.h index c75c4e99b..0926457da 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -162,8 +162,17 @@ template class SizeChecker; TypeName(const TypeName &); \ void operator =(const TypeName &) +// A macro that is used to mark unused local variables, to avoid pedantic warnings in gcc / clang / MSVC +// Note that in MSVC it requires the full type of X to be known +#define UNUSED_VAR(X) (void)(X) + // A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc -#define UNUSED(X) (void)(X) +// Written so that the full type of param needn't be known +#ifdef _MSC_VER + #define UNUSED(X) +#else + #define UNUSED UNUSED_VAR +#endif diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index ebf99103f..c6225eacf 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -213,8 +213,8 @@ public: // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4 char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4 - UNUSED(Check1); - UNUSED(Check2); + UNUSED_VAR(Check1); + UNUSED_VAR(Check2); Int32 i = GetBEInt(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); float f; @@ -229,8 +229,8 @@ public: // If your platform produces a compiler error here, you'll need to add code that manually decodes 64-bit doubles char Check1[9 - sizeof(double)]; // Fails if sizeof(double) > 8 char Check2[sizeof(double) - 7]; // Fails if sizeof(double) < 8 - UNUSED(Check1); - UNUSED(Check2); + UNUSED_VAR(Check1); + UNUSED_VAR(Check2); ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Double); return NetworkToHostDouble8(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); -- cgit v1.2.3 From 30f9a4d3abf9cf7f2b7b9f38d46bbb497e8f6b93 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Sat, 27 Sep 2014 14:19:45 +0200 Subject: Fixed convertToPickups for doors --- src/Blocks/BlockDoor.h | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index b2f9e4dcd..af6eee290 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -55,7 +55,44 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0)); + switch (m_BlockType) + { + case E_BLOCK_WOODEN_DOOR: + { + a_Pickups.Add(E_ITEM_WOODEN_DOOR); + break; + } + case E_BLOCK_ACACIA_DOOR: + { + a_Pickups.Add(E_ITEM_ACACIA_DOOR); + break; + } + case E_BLOCK_BIRCH_DOOR: + { + a_Pickups.Add(E_ITEM_BIRCH_DOOR); + break; + } + case E_BLOCK_DARK_OAK_DOOR: + { + a_Pickups.Add(E_ITEM_DARK_OAK_DOOR); + break; + } + case E_BLOCK_JUNGLE_DOOR: + { + a_Pickups.Add(E_ITEM_JUNGLE_DOOR); + break; + } + case E_BLOCK_SPRUCE_DOOR: + { + a_Pickups.Add(E_ITEM_SPRUCE_DOOR); + break; + } + case E_BLOCK_IRON_DOOR: + { + a_Pickups.Add(E_ITEM_IRON_DOOR); + break; + } + } } -- cgit v1.2.3 From 485bac281880e5828a8359b0197608f9bb964bb7 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Sat, 27 Sep 2014 14:23:58 +0200 Subject: Fixed convertToPickups for fence gates --- src/Blocks/BlockFenceGate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index 3041dd46c..b5c1323bd 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -19,7 +19,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.Add(E_BLOCK_FENCE_GATE, 1, 0); // Reset meta to zero + a_Pickups.Add(m_BlockType, 1, 0); // Reset meta to zero } -- cgit v1.2.3 From 6dd47e783af33cc7eecaf1837899c213bc09f954 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Sat, 27 Sep 2014 15:11:35 +0200 Subject: Added default value to switch and spruce gate to fence gate handler --- src/Blocks/BlockDoor.h | 5 +++++ src/Blocks/BlockHandler.cpp | 1 + 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index af6eee290..0ff8bcfc8 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -92,6 +92,11 @@ public: a_Pickups.Add(E_ITEM_IRON_DOOR); break; } + default: + { + ASSERT(!"Unhandled door type!"); + break; + } } } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 7bfff0545..ff0b201e7 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -294,6 +294,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_SIGN_POST: return new cBlockSignPostHandler (a_BlockType); case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType); + case E_BLOCK_SPRUCE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType); -- cgit v1.2.3 From 72c087cfd335b015139cb73ae78f74105d855cf0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 27 Sep 2014 14:28:14 +0100 Subject: Dropped support for <1.7.x --- src/ClientHandle.cpp | 14 - src/ClientHandle.h | 1 - src/Protocol/CMakeLists.txt | 10 - src/Protocol/Protocol.h | 101 +- src/Protocol/Protocol125.cpp | 2175 ----------------------------------- src/Protocol/Protocol125.h | 185 --- src/Protocol/Protocol132.cpp | 880 -------------- src/Protocol/Protocol132.h | 115 -- src/Protocol/Protocol14x.cpp | 265 ----- src/Protocol/Protocol14x.h | 63 - src/Protocol/Protocol15x.cpp | 209 ---- src/Protocol/Protocol15x.h | 42 - src/Protocol/Protocol16x.cpp | 312 ----- src/Protocol/Protocol16x.h | 78 -- src/Protocol/Protocol17x.cpp | 14 - src/Protocol/Protocol17x.h | 3 - src/Protocol/Protocol18x.cpp | 14 - src/Protocol/Protocol18x.h | 3 - src/Protocol/ProtocolRecognizer.cpp | 205 +--- src/Protocol/ProtocolRecognizer.h | 32 +- src/Root.cpp | 12 - src/Root.h | 6 - 22 files changed, 6 insertions(+), 4733 deletions(-) delete mode 100644 src/Protocol/Protocol125.cpp delete mode 100644 src/Protocol/Protocol125.h delete mode 100644 src/Protocol/Protocol132.cpp delete mode 100644 src/Protocol/Protocol132.h delete mode 100644 src/Protocol/Protocol14x.cpp delete mode 100644 src/Protocol/Protocol14x.h delete mode 100644 src/Protocol/Protocol15x.cpp delete mode 100644 src/Protocol/Protocol15x.h delete mode 100644 src/Protocol/Protocol16x.cpp delete mode 100644 src/Protocol/Protocol16x.h (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 878d309c9..9858aa991 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1741,20 +1741,6 @@ void cClientHandle::HandleRespawn(void) -void cClientHandle::HandleDisconnect(const AString & a_Reason) -{ - LOGD("Received d/c packet from %s with reason \"%s\"", m_Username.c_str(), a_Reason.c_str()); - - cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, a_Reason); - - m_HasSentDC = true; - Destroy(); -} - - - - - void cClientHandle::HandleKeepAlive(int a_KeepAliveID) { if (a_KeepAliveID == m_PingID) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 0a936a2ca..10cf6ae28 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -239,7 +239,6 @@ public: void HandleAnimation (char a_Animation); void HandleChat (const AString & a_Message); void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem); - void HandleDisconnect (const AString & a_Reason); void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching); void HandleEntityLeaveBed (int a_EntityID); void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt index 5426c58fa..7c97e67bc 100644 --- a/src/Protocol/CMakeLists.txt +++ b/src/Protocol/CMakeLists.txt @@ -8,11 +8,6 @@ SET (SRCS Authenticator.cpp ChunkDataSerializer.cpp MojangAPI.cpp - Protocol125.cpp - Protocol132.cpp - Protocol14x.cpp - Protocol15x.cpp - Protocol16x.cpp Protocol17x.cpp Protocol18x.cpp ProtocolRecognizer.cpp) @@ -22,11 +17,6 @@ SET (HDRS ChunkDataSerializer.h MojangAPI.h Protocol.h - Protocol125.h - Protocol132.h - Protocol14x.h - Protocol15x.h - Protocol16x.h Protocol17x.h Protocol18x.h ProtocolRecognizer.h) diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index b2ee92918..7225f663d 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -138,108 +138,9 @@ public: protected: cClientHandle * m_Client; cCriticalSection m_CSPacket; // Each SendXYZ() function must acquire this CS in order to send the whole packet at once - + /// A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it virtual void SendData(const char * a_Data, size_t a_Size) = 0; - - /// Called after writing each packet, enables descendants to flush their buffers - virtual void Flush(void) {} - - // Helpers for writing partial packet data, write using SendData() - void WriteByte(Byte a_Value) - { - SendData((const char *)&a_Value, 1); - } - - void WriteChar(char a_Value) - { - SendData(&a_Value, 1); - } - - void WriteShort(short a_Value) - { - u_short Value = htons((u_short)a_Value); - SendData((const char *)&Value, 2); - } - - /* - void WriteShort(unsigned short a_Value) - { - a_Value = htons(a_Value); - SendData((const char *)&a_Value, 2); - } - */ - - void WriteInt(int a_Value) - { - u_long Value = htonl((u_long)a_Value); - SendData((const char *)&Value, 4); - } - - void WriteUInt(unsigned int a_Value) - { - a_Value = htonl(a_Value); - SendData((const char *)&a_Value, 4); - } - - void WriteInt64 (Int64 a_Value) - { - UInt64 Value = HostToNetwork8(&a_Value); - SendData((const char *)&Value, 8); - } - - void WriteFloat (float a_Value) - { - UInt32 val = HostToNetwork4(&a_Value); - SendData((const char *)&val, 4); - } - - void WriteDouble(double a_Value) - { - UInt64 val = HostToNetwork8(&a_Value); - SendData((const char *)&val, 8); - } - - void WriteString(const AString & a_Value) - { - AString UTF16; - UTF8ToRawBEUTF16(a_Value.c_str(), a_Value.length(), UTF16); - WriteShort((short)(UTF16.size() / 2)); - SendData(UTF16.data(), UTF16.size()); - } - - void WriteBool(bool a_Value) - { - WriteByte(a_Value ? 1 : 0); - } - - void WriteVectorI(const Vector3i & a_Vector) - { - WriteInt(a_Vector.x); - WriteInt(a_Vector.y); - WriteInt(a_Vector.z); - } - - void WriteVarInt(UInt32 a_Value) - { - // A 32-bit integer can be encoded by at most 5 bytes: - unsigned char b[5]; - size_t idx = 0; - do - { - b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00); - a_Value = a_Value >> 7; - idx++; - } while (a_Value > 0); - - SendData((const char *)b, idx); - } - - void WriteVarUTF8String(const AString & a_String) - { - WriteVarInt((UInt32)a_String.size()); - SendData(a_String.data(), a_String.size()); - } } ; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp deleted file mode 100644 index 369a35e18..000000000 --- a/src/Protocol/Protocol125.cpp +++ /dev/null @@ -1,2175 +0,0 @@ - -// Protocol125.cpp - -// Implements the cProtocol125 class representing the release 1.2.5 protocol (#29) -/* -Documentation: - - protocol: http://wiki.vg/wiki/index.php?title=Protocol&oldid=2513 - - session handling: http://wiki.vg/wiki/index.php?title=Session&oldid=2262 - - slot format: http://wiki.vg/wiki/index.php?title=Slot_Data&oldid=2152 -*/ - -#include "Globals.h" - -#include "Protocol125.h" - -#include "../ClientHandle.h" -#include "../World.h" -#include "ChunkDataSerializer.h" -#include "../Entities/Entity.h" -#include "../Entities/ExpOrb.h" -#include "../Mobs/Monster.h" -#include "../Entities/Pickup.h" -#include "../Entities/Player.h" -#include "../ChatColor.h" -#include "../UI/Window.h" -#include "../Root.h" -#include "../Server.h" - -#include "../Entities/ArrowEntity.h" -#include "../Entities/Minecart.h" -#include "../Entities/FallingBlock.h" - -#include "../Mobs/IncludeAllMonsters.h" - -#include "../CompositeChat.h" - - - - - -enum -{ - PACKET_KEEP_ALIVE = 0x00, - PACKET_LOGIN = 0x01, - PACKET_HANDSHAKE = 0x02, - PACKET_CHAT = 0x03, - PACKET_UPDATE_TIME = 0x04, - PACKET_ENTITY_EQUIPMENT = 0x05, - PACKET_USE_ENTITY = 0x07, - PACKET_UPDATE_HEALTH = 0x08, - PACKET_RESPAWN = 0x09, - PACKET_PLAYER_ON_GROUND = 0x0a, - PACKET_PLAYER_POS = 0x0b, - PACKET_PLAYER_LOOK = 0x0c, - PACKET_PLAYER_MOVE_LOOK = 0x0d, - PACKET_BLOCK_DIG = 0x0e, - PACKET_BLOCK_PLACE = 0x0f, - PACKET_SLOT_SELECTED = 0x10, - PACKET_USE_BED = 0x11, - PACKET_ANIMATION = 0x12, - PACKET_PACKET_ENTITY_ACTION = 0x13, - PACKET_PLAYER_SPAWN = 0x14, - PACKET_PICKUP_SPAWN = 0x15, - PACKET_COLLECT_PICKUP = 0x16, - PACKET_SPAWN_OBJECT = 0x17, - PACKET_SPAWN_MOB = 0x18, - PACKET_ENTITY_VELOCITY = 0x1c, - PACKET_DESTROY_ENTITY = 0x1d, - PACKET_ENTITY = 0x1e, - PACKET_ENT_REL_MOVE = 0x1f, - PACKET_ENT_LOOK = 0x20, - PACKET_ENT_REL_MOVE_LOOK = 0x21, - PACKET_ENT_TELEPORT = 0x22, - PACKET_ENT_HEAD_LOOK = 0x23, - PACKET_ENT_STATUS = 0x26, - PACKET_ATTACH_ENTITY = 0x27, - PACKET_METADATA = 0x28, - PACKET_ENTITY_EFFECT = 0x29, - PACKET_SPAWN_EXPERIENCE_ORB = 0x1A, - PACKET_REMOVE_ENTITY_EFFECT = 0x2a, - PACKET_EXPERIENCE = 0x2b, - PACKET_PRE_CHUNK = 0x32, - PACKET_MAP_CHUNK = 0x33, - PACKET_MULTI_BLOCK = 0x34, - PACKET_BLOCK_CHANGE = 0x35, - PACKET_BLOCK_ACTION = 0x36, - PACKET_EXPLOSION = 0x3C, - PACKET_SOUND_EFFECT = 0x3e, - PACKET_SOUND_PARTICLE_EFFECT = 0x3d, - PACKET_CHANGE_GAME_STATE = 0x46, - PACKET_THUNDERBOLT = 0x47, - PACKET_WINDOW_OPEN = 0x64, - PACKET_WINDOW_CLOSE = 0x65, - PACKET_WINDOW_CLICK = 0x66, - PACKET_INVENTORY_SLOT = 0x67, - PACKET_INVENTORY_WHOLE = 0x68, - PACKET_WINDOW_PROPERTY = 0x69, - PACKET_CREATIVE_INVENTORY_ACTION = 0x6B, - PACKET_ENCHANT_ITEM = 0x6C, - PACKET_UPDATE_SIGN = 0x82, - PACKET_ITEM_DATA = 0x83, - PACKET_INCREMENT_STATISTIC = 0xC8, - PACKET_PLAYER_LIST_ITEM = 0xC9, - PACKET_PLAYER_ABILITIES = 0xca, - PACKET_PLUGIN_MESSAGE = 0xfa, - PACKET_PING = 0xfe, - PACKET_DISCONNECT = 0xff -} ; - - - - - -#define HANDLE_PACKET_READ(Proc, Type, Var) \ - Type Var; \ - { \ - if (!m_ReceivedData.Proc(Var)) \ - { \ - m_ReceivedData.CheckValid(); \ - return PARSE_INCOMPLETE; \ - } \ - m_ReceivedData.CheckValid(); \ - } - - - - -typedef unsigned char Byte; - - - - - -cProtocol125::cProtocol125(cClientHandle * a_Client) : - super(a_Client), - m_ReceivedData(32 KiB), - m_LastSentDimension(dimNotSet) -{ -} - - - - - -void cProtocol125::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ATTACH_ENTITY); - WriteInt(a_Entity.GetUniqueID()); - WriteInt((a_Vehicle == NULL) ? -1 : a_Vehicle->GetUniqueID()); - Flush(); -} - - - - - -void cProtocol125::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) -{ - UNUSED(a_BlockType); - - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_BLOCK_ACTION); - WriteInt (a_BlockX); - WriteShort((short)a_BlockY); - WriteInt (a_BlockZ); - WriteChar (a_Byte1); - WriteChar (a_Byte2); - Flush(); -} - - - - - -void cProtocol125::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) -{ - // Not supported in this protocol version -} - - - - - -void cProtocol125::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_BLOCK_CHANGE); - WriteInt (a_BlockX); - WriteByte((unsigned char)a_BlockY); - WriteInt (a_BlockZ); - WriteByte(a_BlockType); - WriteByte(a_BlockMeta); - Flush(); -} - - - - - -void cProtocol125::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) -{ - cCSLock Lock(m_CSPacket); - if (a_Changes.size() == 1) - { - // Special packet for single-block changes - const sSetBlock & blk = a_Changes.front(); - SendBlockChange(a_ChunkX * cChunkDef::Width + blk.x, blk.y, a_ChunkZ * cChunkDef::Width + blk.z, blk.BlockType, blk.BlockMeta); - return; - } - - WriteByte (PACKET_MULTI_BLOCK); - WriteInt (a_ChunkX); - WriteInt (a_ChunkZ); - WriteShort((short)a_Changes.size()); - WriteUInt ((UInt32)(4 * a_Changes.size())); - for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) - { - UInt32 Coords = ((UInt32)itr->y) | ((UInt32)(itr->z << 8)) | ((UInt32)(itr->x << 12)); - UInt32 Blocks = ((UInt32)itr->BlockMeta) | ((UInt32)(itr->BlockType << 4)); - WriteUInt(Coords << 16 | Blocks); - } - Flush(); -} - - - - - -void cProtocol125::SendChat(const AString & a_Message) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_CHAT); - WriteString(a_Message); - Flush(); -} - - - - - -void cProtocol125::SendChat(const cCompositeChat & a_Message) -{ - // This version doesn't support composite messages, just extract each part's text and use it: - - // Send the message: - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_CHAT); - WriteString(a_Message.ExtractText()); - Flush(); -} - - - - - -void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) -{ - cCSLock Lock(m_CSPacket); - - // Send the pre-chunk: - SendPreChunk(a_ChunkX, a_ChunkZ, true); - - // Send the chunk data: - AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_2_5, a_ChunkX, a_ChunkZ); - WriteByte(PACKET_MAP_CHUNK); - WriteInt (a_ChunkX); - WriteInt (a_ChunkZ); - SendData(Serialized.data(), Serialized.size()); - Flush(); -} - - - - - -void cProtocol125::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_COLLECT_PICKUP); - WriteInt (a_Entity.GetUniqueID()); - WriteInt (a_Player.GetUniqueID()); - Flush(); -} - - - - - -void cProtocol125::SendDestroyEntity(const cEntity & a_Entity) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_DESTROY_ENTITY); - WriteInt (a_Entity.GetUniqueID()); - Flush(); -} - - - - - -void cProtocol125::SendDisconnect(const AString & a_Reason) -{ - cCSLock Lock(m_CSPacket); - WriteByte ((unsigned char)PACKET_DISCONNECT); - WriteString(a_Reason); - Flush(); -} - - - - - -void cProtocol125::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - // This protocol version doesn't support this packet, sign editor is invoked by the client automatically - UNUSED(a_BlockX); - UNUSED(a_BlockY); - UNUSED(a_BlockZ); -} - - - - - -void cProtocol125::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_ENTITY_EFFECT); - WriteInt (a_Entity.GetUniqueID()); - WriteByte ((Byte)a_EffectID); - WriteByte ((Byte)a_Amplifier); - WriteShort(a_Duration); - Flush(); -} - - - - - -void cProtocol125::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_ENTITY_EQUIPMENT); - WriteInt (a_Entity.GetUniqueID()); - WriteShort(a_SlotNum); - WriteShort(a_Item.m_ItemType); - WriteShort(a_Item.m_ItemDamage); - Flush(); -} - - - - - -void cProtocol125::SendEntityHeadLook(const cEntity & a_Entity) -{ - ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENT_HEAD_LOOK); - WriteInt (a_Entity.GetUniqueID()); - WriteChar((char)((a_Entity.GetHeadYaw() / 360.f) * 256)); - Flush(); -} - - - - - -void cProtocol125::SendEntityLook(const cEntity & a_Entity) -{ - ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENT_LOOK); - WriteInt (a_Entity.GetUniqueID()); - WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256)); - Flush(); -} - - - - - -void cProtocol125::SendEntityMetadata(const cEntity & a_Entity) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_METADATA); - WriteInt (a_Entity.GetUniqueID()); - - WriteCommonMetadata(a_Entity); - if (a_Entity.IsMob()) - { - WriteMobMetadata(((const cMonster &)a_Entity)); - } - else - { - WriteEntityMetadata(a_Entity); - } - WriteByte(0x7f); - - Flush(); -} - - - - - -void cProtocol125::SendEntityProperties(const cEntity & a_Entity) -{ - // Not supported in this protocol version -} - - - - - -void cProtocol125::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) -{ - ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENT_REL_MOVE); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_RelX); - WriteChar(a_RelY); - WriteChar(a_RelZ); - Flush(); -} - - - - - -void cProtocol125::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) -{ - ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENT_REL_MOVE_LOOK); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_RelX); - WriteChar(a_RelY); - WriteChar(a_RelZ); - WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256)); - Flush(); -} - - - - - -void cProtocol125::SendEntityStatus(const cEntity & a_Entity, char a_Status) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENT_STATUS); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_Status); - Flush(); -} - - - - - -void cProtocol125::SendEntityVelocity(const cEntity & a_Entity) -{ - ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENTITY_VELOCITY); - WriteInt (a_Entity.GetUniqueID()); - WriteShort((short) (a_Entity.GetSpeedX() * 400)); // 400 = 8000 / 20 - WriteShort((short) (a_Entity.GetSpeedY() * 400)); - WriteShort((short) (a_Entity.GetSpeedZ() * 400)); - Flush(); -} - - - - - -void cProtocol125::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_EXPLOSION); - WriteDouble (a_BlockX); - WriteDouble (a_BlockY); - WriteDouble (a_BlockZ); - WriteFloat (a_Radius); - WriteInt ((Int32)a_BlocksAffected.size()); - int BlockX = (int)a_BlockX; - int BlockY = (int)a_BlockY; - int BlockZ = (int)a_BlockZ; - for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(); itr != a_BlocksAffected.end(); ++itr) - { - WriteByte((Byte)(itr->x - BlockX)); - WriteByte((Byte)(itr->y - BlockY)); - WriteByte((Byte)(itr->z - BlockZ)); - } - WriteFloat((float)a_PlayerMotion.x); - WriteFloat((float)a_PlayerMotion.y); - WriteFloat((float)a_PlayerMotion.z); - Flush(); -} - - - - - -void cProtocol125::SendGameMode(eGameMode a_GameMode) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_CHANGE_GAME_STATE); - WriteByte(3); - WriteChar((char)a_GameMode); - Flush(); -} - - - - - -void cProtocol125::SendHandshake(const AString & a_ConnectionHash) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_HANDSHAKE); - WriteString(a_ConnectionHash); - Flush(); -} - - - - - -void cProtocol125::SendHealth(void) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_UPDATE_HEALTH); - cPlayer * Player = m_Client->GetPlayer(); - WriteShort((short)Player->GetHealth()); - WriteShort((short)Player->GetFoodLevel()); - WriteFloat((float)Player->GetFoodSaturationLevel()); - Flush(); -} - - - - - -void cProtocol125::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_INVENTORY_SLOT); - WriteChar (a_WindowID); - WriteShort(a_SlotNum); - WriteItem (a_Item); - Flush(); -} - - - - - -void cProtocol125::SendKeepAlive(int a_PingID) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_KEEP_ALIVE); - WriteInt (a_PingID); - Flush(); -} - - - - - -void cProtocol125::SendLogin(const cPlayer & a_Player, const cWorld & a_World) -{ - UNUSED(a_World); - cCSLock Lock(m_CSPacket); - - WriteByte (PACKET_LOGIN); - WriteInt (a_Player.GetUniqueID()); // EntityID of the player - WriteString(""); // Username, not used - WriteString("default"); // Level type - WriteInt ((int)a_Player.GetGameMode()); - WriteInt ((int)(a_World.GetDimension())); - WriteByte (2); // TODO: Difficulty - WriteByte (0); // Unused - WriteByte (60); // Client list width or something - Flush(); - m_LastSentDimension = a_World.GetDimension(); -} - - - - - -void cProtocol125::SendLoginSuccess(void) -{ - // Not supported in this protocol version -} - - - - - -void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) -{ - cCSLock Lock(m_CSPacket); - - WriteByte (PACKET_ITEM_DATA); - WriteShort(E_ITEM_MAP); - WriteShort((short)a_ID); - WriteShort((short)(3 + a_Length)); - - WriteByte(0); - WriteChar((char)a_X); - WriteChar((char)a_Y); - - SendData((const char *)a_Colors, a_Length); - - Flush(); -} - - - - - -void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) -{ - cCSLock Lock(m_CSPacket); - - WriteByte (PACKET_ITEM_DATA); - WriteShort(E_ITEM_MAP); - WriteShort((short)a_ID); - WriteShort((short)(1 + (3 * a_Decorators.size()))); - - WriteByte(1); - - for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it) - { - WriteByte((Byte)(it->GetType() << 4) | (it->GetRot() & 0xf)); - WriteByte((Byte)it->GetPixelX()); - WriteByte((Byte)it->GetPixelZ()); - } - - Flush(); -} - - - - - - -void cProtocol125::SendMapInfo(int a_ID, unsigned int a_Scale) -{ - // This protocol doesn't support such message - UNUSED(a_ID); - UNUSED(a_Scale); -} - - - - - -void cProtocol125::SendPickupSpawn(const cPickup & a_Pickup) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PICKUP_SPAWN); - WriteInt (a_Pickup.GetUniqueID()); - const cItem & Item = a_Pickup.GetItem(); - WriteShort (Item.m_ItemType); - WriteChar (Item.m_ItemCount); - WriteShort (Item.m_ItemDamage); - WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32)); - WriteByte ((char)(a_Pickup.GetSpeedX() * 8)); - WriteByte ((char)(a_Pickup.GetSpeedY() * 8)); - WriteByte ((char)(a_Pickup.GetSpeedZ() * 8)); - Flush(); -} - - - - - -void cProtocol125::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ANIMATION); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_Animation); - Flush(); -} - - - - - -void cProtocol125::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) -{ - // Not supported by this protocol version -} - - - - - -void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting) -{ - // Not implemented in this protocol version - UNUSED(a_Painting); -} - - - - - -void cProtocol125::SendPlayerListAddPlayer(const cPlayer & a_Player) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PLAYER_LIST_ITEM); - WriteString(a_Player.GetPlayerListName()); - WriteBool (true); - WriteShort (a_Player.GetClientHandle()->GetPing()); - Flush(); -} - - - - - -void cProtocol125::SendPlayerListRemovePlayer(const cPlayer & a_Player) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PLAYER_LIST_ITEM); - WriteString(a_Player.GetPlayerListName()); - WriteBool (false); - WriteShort (0); - Flush(); -} - - - - - -void cProtocol125::SendPlayerListUpdateGameMode(const cPlayer & a_Player) -{ - // Not implemented in this protocol version - UNUSED(a_Player); -} - - - - - -void cProtocol125::SendPlayerListUpdatePing(const cPlayer & a_Player) -{ - // It is a simple add player packet in this protocol. - SendPlayerListAddPlayer(a_Player); -} - - - - - -void cProtocol125::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) -{ - // Not implemented in this protocol version - UNUSED(a_Player); - UNUSED(a_CustomName); -} - - - - - -void cProtocol125::SendPlayerMaxSpeed(void) -{ - // Not supported by this protocol version -} - - - - - -void cProtocol125::SendPlayerMoveLook(void) -{ - cCSLock Lock(m_CSPacket); - - /* - LOGD("Sending PlayerMoveLook: {%0.2f, %0.2f, %0.2f}, stance %0.2f, OnGround: %d", - m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ(), m_Player->GetStance(), m_Player->IsOnGround() ? 1 : 0 - ); - */ - - WriteByte(PACKET_PLAYER_MOVE_LOOK); - cPlayer * Player = m_Client->GetPlayer(); - WriteDouble(Player->GetPosX()); - WriteDouble(Player->GetStance() + 0.03); // Add a small amount so that the player doesn't start inside a block - WriteDouble(Player->GetPosY() + 0.03); // Add a small amount so that the player doesn't start inside a block - WriteDouble(Player->GetPosZ()); - WriteFloat ((float)(Player->GetYaw())); - WriteFloat ((float)(Player->GetPitch())); - WriteBool (Player->IsOnGround()); - Flush(); -} - - - - - -void cProtocol125::SendPlayerPosition(void) -{ - cCSLock Lock(m_CSPacket); - LOGD("Ignore send PlayerPos"); // PlayerPos is a C->S packet only now -} - - - - - -void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) -{ - const cItem & HeldItem = a_Player.GetEquippedItem(); - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PLAYER_SPAWN); - WriteInt (a_Player.GetUniqueID()); - if (a_Player.HasCustomName()) - { - WriteString(a_Player.GetCustomName()); - } - else - { - WriteString(a_Player.GetName()); - } - WriteInt ((int)(a_Player.GetPosX() * 32)); - WriteInt ((int)(a_Player.GetPosY() * 32)); - WriteInt ((int)(a_Player.GetPosZ() * 32)); - WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); - WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); - WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); - Flush(); -} - - - - - -void cProtocol125::SendPluginMessage(const AString & a_Channel, const AString & a_Message) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_PLUGIN_MESSAGE); - WriteString(a_Channel); - WriteShort((short)a_Message.size()); - SendData(a_Message.data(), a_Message.size()); - Flush(); -} - - - - - -void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_REMOVE_ENTITY_EFFECT); - WriteInt (a_Entity.GetUniqueID()); - WriteChar((char)a_EffectID); - Flush(); -} - - - - - -void cProtocol125::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) -{ - cCSLock Lock(m_CSPacket); - if ((m_LastSentDimension == a_Dimension) && !a_ShouldIgnoreDimensionChecks) - { - // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death) - return; - } - cPlayer * Player = m_Client->GetPlayer(); - WriteByte (PACKET_RESPAWN); - WriteInt ((int)(a_Dimension)); - WriteByte (2); // TODO: Difficulty; 2 = Normal - WriteChar ((char)Player->GetGameMode()); - WriteShort (256); // Current world height - WriteString("default"); - Flush(); - m_LastSentDimension = a_Dimension; -} - - - - - -void cProtocol125::SendExperience(void) -{ - cCSLock Lock(m_CSPacket); - cPlayer * Player = m_Client->GetPlayer(); - WriteByte (PACKET_EXPERIENCE); - WriteFloat (Player->GetXpPercentage()); - WriteShort (Player->GetXpLevel()); - WriteShort (Player->GetCurrentXp()); - Flush(); -} - - - - - -void cProtocol125::SendExperienceOrb(const cExpOrb & a_ExpOrb) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SPAWN_EXPERIENCE_ORB); - WriteInt(a_ExpOrb.GetUniqueID()); - WriteInt((int) a_ExpOrb.GetPosX()); - WriteInt((int) a_ExpOrb.GetPosY()); - WriteInt((int) a_ExpOrb.GetPosZ()); - WriteShort((short)a_ExpOrb.GetReward()); - Flush(); -} - - - - - -void cProtocol125::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) -{ - // This protocol version doesn't support such message - UNUSED(a_Name); - UNUSED(a_DisplayName); - UNUSED(a_Mode); -} - - - - - -void cProtocol125::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) -{ - // Not needed in this protocol version -} - - - - - -void cProtocol125::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) -{ - // Not implemented in this protocol version -} - - - - - -void cProtocol125::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) -{ - // This protocol version implements falling blocks using the spawn object / vehicle packet: - SendSpawnObject(a_FallingBlock, 70, a_FallingBlock.GetBlockType(), 0, 0); -} - - - - - -void cProtocol125::SendSpawnMob(const cMonster & a_Mob) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_SPAWN_MOB); - WriteInt (a_Mob.GetUniqueID()); - WriteByte ((Byte)a_Mob.GetMobType()); - WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32)); - WriteByte (0); - WriteByte (0); - WriteByte (0); - - WriteCommonMetadata(a_Mob); - WriteMobMetadata(a_Mob); - WriteByte(0x7f); - - Flush(); -} - - - - - -void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) -{ - UNUSED(a_Yaw); - UNUSED(a_Pitch); - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SPAWN_OBJECT); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_ObjectType); - WriteInt ((int)(a_Entity.GetPosX() * 32)); - WriteInt ((int)(a_Entity.GetPosY() * 32)); - WriteInt ((int)(a_Entity.GetPosZ() * 32)); - WriteByte(a_Pitch); - WriteByte(a_Yaw); - WriteInt (a_ObjectData); - if (a_ObjectData != 0) - { - WriteShort((short)(a_Entity.GetSpeedX() * 400)); - WriteShort((short)(a_Entity.GetSpeedY() * 400)); - WriteShort((short)(a_Entity.GetSpeedZ() * 400)); - } - Flush(); -} - - - - - -void cProtocol125::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_SPAWN_OBJECT); - WriteInt (a_Vehicle.GetUniqueID()); - WriteChar (a_VehicleType); - WriteInt ((int)(a_Vehicle.GetPosX() * 32)); - WriteInt ((int)(a_Vehicle.GetPosY() * 32)); - WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); - WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256)); - WriteByte ((Byte)((a_Vehicle.GetYaw() / 360.f) * 256)); - WriteInt (a_VehicleSubType); - if (a_VehicleSubType != 0) - { - WriteShort((short)(a_Vehicle.GetSpeedX() * 400)); - WriteShort((short)(a_Vehicle.GetSpeedY() * 400)); - WriteShort((short)(a_Vehicle.GetSpeedZ() * 400)); - } - Flush(); -} - - - - - -void cProtocol125::SendStatistics(const cStatManager & a_Manager) -{ - /* NOTE: - Versions prior to minecraft 1.7 use an incremental statistic sync - method. The current setup does not allow us to implement that, because - of performance considerations. - */ -#if 0 - for (unsigned int i = 0; i < (unsigned int)statCount; ++i) - { - StatValue Value = m_Manager->GetValue((eStatistic) i); - - unsigned int StatID = cStatInfo::GetID((eStatistic) i); - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_INCREMENT_STATISTIC); - WriteInt(StatID); - WriteByte(Value); /* Can overflow! */ - Flush(); - } -#endif -} - - - - - -void cProtocol125::SendTabCompletionResults(const AStringVector & a_Results) -{ - // This protocol version doesn't support tab completion - UNUSED(a_Results); -} - - - - - -void cProtocol125::SendTeleportEntity(const cEntity & a_Entity) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_ENT_TELEPORT); - WriteInt (a_Entity.GetUniqueID()); - WriteInt ((int)(floor(a_Entity.GetPosX() * 32))); - WriteInt ((int)(floor(a_Entity.GetPosY() * 32))); - WriteInt ((int)(floor(a_Entity.GetPosZ() * 32))); - WriteChar ((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteChar ((char)((a_Entity.GetPitch() / 360.f) * 256)); - Flush(); -} - - - - - -void cProtocol125::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_THUNDERBOLT); - WriteInt (0x7fffffff); // Entity ID of the thunderbolt; we use a constant one - WriteBool(true); // Unknown bool - WriteInt (a_BlockX * 32); - WriteInt (a_BlockY * 32); - WriteInt (a_BlockZ * 32); - Flush(); -} - - - - - -void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) -{ - // This protocol doesn't support a_DoDaylightCycle on false. - UNUSED(a_DoDaylightCycle); - - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_UPDATE_TIME); - // Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day: - WriteInt64((24000 * (a_WorldAge / 24000)) + (a_TimeOfDay % 24000)); - Flush(); -} - - - - - -void cProtocol125::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -{ - cCSLock Lock(m_CSPacket); - SendPreChunk(a_ChunkX, a_ChunkZ, false); -} - - - - - -void cProtocol125::SendUpdateSign( - int a_BlockX, int a_BlockY, int a_BlockZ, - const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 -) -{ - cCSLock Lock(m_CSPacket); - WriteByte ((unsigned char)PACKET_UPDATE_SIGN); - WriteInt (a_BlockX); - WriteShort ((short)a_BlockY); - WriteInt (a_BlockZ); - WriteString(a_Line1); - WriteString(a_Line2); - WriteString(a_Line3); - WriteString(a_Line4); - Flush(); -} - - - - - -void cProtocol125::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_USE_BED); - WriteInt (a_Entity.GetUniqueID()); - WriteByte(0); // Unknown byte only 0 has been observed - WriteInt (a_BlockX); - WriteByte((Byte)a_BlockY); - WriteInt (a_BlockZ); - Flush(); -} - - - - - -void cProtocol125::SendWeather(eWeather a_Weather) -{ - cCSLock Lock(m_CSPacket); - switch (a_Weather) - { - case eWeather_Sunny: - { - WriteByte(PACKET_CHANGE_GAME_STATE); - WriteByte(2); // Stop rain - WriteByte(0); // Unused - Flush(); - break; - } - - case eWeather_Rain: - case eWeather_ThunderStorm: - { - WriteByte(PACKET_CHANGE_GAME_STATE); - WriteByte(1); // Begin rain - WriteByte(0); // Unused - Flush(); - break; - } - } -} - - - - - -void cProtocol125::SendWholeInventory(const cWindow & a_Window) -{ - cCSLock Lock(m_CSPacket); - cItems Slots; - a_Window.GetSlots(*(m_Client->GetPlayer()), Slots); - SendWindowSlots(a_Window.GetWindowID(), (int)Slots.size(), &(Slots[0])); -} - - - - - -void cProtocol125::SendWindowClose(const cWindow & a_Window) -{ - if (a_Window.GetWindowType() == cWindow::wtInventory) - { - // Do not send inventory-window-close - return; - } - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_WINDOW_CLOSE); - WriteChar(a_Window.GetWindowID()); - Flush(); -} - - - - - -void cProtocol125::SendWindowOpen(const cWindow & a_Window) -{ - if (a_Window.GetWindowType() < 0) - { - // Do not send for inventory windows - return; - } - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_WINDOW_OPEN); - WriteChar (a_Window.GetWindowID()); - WriteByte ((Byte)a_Window.GetWindowType()); - WriteString(a_Window.GetWindowTitle()); - WriteByte ((Byte)a_Window.GetNumNonInventorySlots()); - Flush(); -} - - - - - -void cProtocol125::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_WINDOW_PROPERTY); - WriteChar (a_Window.GetWindowID()); - WriteShort(a_Property); - WriteShort(a_Value); - Flush(); -} - - - - - -AString cProtocol125::GetAuthServerID(void) -{ - // http://wiki.vg/wiki/index.php?title=Session&oldid=2262 - // The server generates a random hash and that is used for all clients, unmodified - return cRoot::Get()->GetServer()->GetServerID(); -} - - - - - -void cProtocol125::SendData(const char * a_Data, size_t a_Size) -{ - m_Client->SendData(a_Data, a_Size); -} - - - - - -void cProtocol125::DataReceived(const char * a_Data, size_t a_Size) -{ - if (!m_ReceivedData.Write(a_Data, a_Size)) - { - // Too much data in the incoming queue, report to caller: - m_Client->PacketBufferFull(); - return; - } - - // Parse and handle all complete packets in m_ReceivedData: - while (m_ReceivedData.CanReadBytes(1)) - { - unsigned char PacketType; - m_ReceivedData.ReadByte(PacketType); - switch (ParsePacket(PacketType)) - { - case PARSE_UNKNOWN: - { - // An unknown packet has been received, notify the client and abort: - m_Client->PacketUnknown(PacketType); - return; - } - case PARSE_ERROR: - { - // An error occurred while parsing a known packet, notify the client and abort: - m_Client->PacketError(PacketType); - return; - } - case PARSE_INCOMPLETE: - { - // Incomplete packet, bail out and process with the next batch of data - m_ReceivedData.ResetRead(); - return; - } - default: - { - // Packet successfully parsed, commit the read data and try again one more packet - m_ReceivedData.CommitRead(); - break; - } - } - } -} - - - - - -int cProtocol125::ParsePacket(unsigned char a_PacketType) -{ - switch (a_PacketType) - { - default: return PARSE_UNKNOWN; - case PACKET_ANIMATION: return ParseArmAnim(); - case PACKET_BLOCK_DIG: return ParseBlockDig(); - case PACKET_BLOCK_PLACE: return ParseBlockPlace(); - case PACKET_CHAT: return ParseChat(); - case PACKET_CREATIVE_INVENTORY_ACTION: return ParseCreativeInventoryAction(); - case PACKET_DISCONNECT: return ParseDisconnect(); - case PACKET_HANDSHAKE: return ParseHandshake(); - case PACKET_KEEP_ALIVE: return ParseKeepAlive(); - case PACKET_LOGIN: return ParseLogin(); - case PACKET_PACKET_ENTITY_ACTION: return ParseEntityAction(); - case PACKET_PING: return ParsePing(); - case PACKET_PLAYER_ABILITIES: return ParsePlayerAbilities(); - case PACKET_PLAYER_LOOK: return ParsePlayerLook(); - case PACKET_PLAYER_MOVE_LOOK: return ParsePlayerMoveLook(); - case PACKET_PLAYER_ON_GROUND: return ParsePlayerOnGround(); - case PACKET_PLAYER_POS: return ParsePlayerPosition(); - case PACKET_PLUGIN_MESSAGE: return ParsePluginMessage(); - case PACKET_RESPAWN: return ParseRespawn(); - case PACKET_SLOT_SELECTED: return ParseSlotSelected(); - case PACKET_UPDATE_SIGN: return ParseUpdateSign(); - case PACKET_USE_ENTITY: return ParseUseEntity(); - case PACKET_ENCHANT_ITEM: return ParseEnchantItem(); - case PACKET_WINDOW_CLICK: return ParseWindowClick(); - case PACKET_WINDOW_CLOSE: return ParseWindowClose(); - } -} - - - - - -int cProtocol125::ParseArmAnim(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_PACKET_READ(ReadChar, char, Animation); - m_Client->HandleAnimation(Animation); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseBlockDig(void) -{ - HANDLE_PACKET_READ(ReadChar, char, Status); - HANDLE_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_PACKET_READ(ReadByte, Byte, PosY); - HANDLE_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_PACKET_READ(ReadChar, char, BlockFace); - m_Client->HandleLeftClick(PosX, PosY, PosZ, static_cast(BlockFace), Status); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseBlockPlace(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_PACKET_READ(ReadByte, Byte, PosY); - HANDLE_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_PACKET_READ(ReadChar, char, BlockFace); - - cItem HeldItem; - int res = ParseItem(HeldItem); - if (res < 0) - { - return res; - } - - // 1.2.5 didn't have any cursor position, so use 8, 8, 8, so that halfslabs and stairs work correctly and the special value is recognizable. - m_Client->HandleRightClick(PosX, PosY, PosZ, static_cast(BlockFace), 8, 8, 8, HeldItem); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseChat(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Message); - m_Client->HandleChat(Message); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseCreativeInventoryAction(void) -{ - HANDLE_PACKET_READ(ReadBEShort, short, SlotNum); - cItem HeldItem; - int res = ParseItem(HeldItem); - if (res < 0) - { - return res; - } - m_Client->HandleCreativeInventory(SlotNum, HeldItem); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseDisconnect(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Reason); - m_Client->HandleDisconnect(Reason); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseEntityAction(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_PACKET_READ(ReadChar, char, ActionID); - - switch (ActionID) - { - case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch - case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch - case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed - case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting - case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting - } - - return PARSE_OK; -} - - - - - -int cProtocol125::ParseHandshake(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username); - - AStringVector UserData = StringSplit(Username, ";"); // "FakeTruth;localhost:25565" - if (UserData.empty()) - { - m_Client->Kick("Did not receive username"); - return PARSE_OK; - } - m_Username = UserData[0]; - - LOGD("HANDSHAKE %s", Username.c_str()); - - if (!m_Client->HandleHandshake( m_Username)) - { - return PARSE_OK; // Player is not allowed into the server - } - - SendHandshake(cRoot::Get()->GetServer()->GetServerID()); - LOGD("User \"%s\" was sent a handshake response", m_Username.c_str()); - - return PARSE_OK; -} - - - - - -int cProtocol125::ParseKeepAlive(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, KeepAliveID); - m_Client->HandleKeepAlive(KeepAliveID); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseLogin(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, ProtocolVersion); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, LevelType); - HANDLE_PACKET_READ(ReadBEInt, int, ServerMode); - HANDLE_PACKET_READ(ReadBEInt, int, Dimension); - HANDLE_PACKET_READ(ReadChar, char, Difficulty); - HANDLE_PACKET_READ(ReadByte, Byte, WorldHeight); - HANDLE_PACKET_READ(ReadByte, Byte, MaxPlayers); - - if (ProtocolVersion < 29) - { - m_Client->Kick("Your client is outdated!"); - return PARSE_OK; - } - else if (ProtocolVersion > 29) - { - m_Client->Kick("Your client version is higher than the server!"); - return PARSE_OK; - } - - if (m_Username.compare(Username) != 0) - { - LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client @ \"%s\", kicking", - Username.c_str(), - m_Username.c_str(), - m_Client->GetIPString().c_str() - ); - m_Client->Kick("Hacked client"); // Don't tell them why we don't want them - return PARSE_OK; - } - - m_Client->HandleLogin(ProtocolVersion, Username); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePing(void) -{ - // Packet has no more data - m_Client->HandlePing(); - return PARSE_OK; -} - - - - - - -int cProtocol125::ParsePlayerAbilities(void) -{ - HANDLE_PACKET_READ(ReadBool, bool, Invulnerable); - HANDLE_PACKET_READ(ReadBool, bool, IsFlying); - HANDLE_PACKET_READ(ReadBool, bool, CanFly); - HANDLE_PACKET_READ(ReadBool, bool, InstaMine); - // TODO: m_Client->HandlePlayerAbilities(...); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePlayerLook(void) -{ - HANDLE_PACKET_READ(ReadBEFloat, float, Rotation); - HANDLE_PACKET_READ(ReadBEFloat, float, Pitch); - HANDLE_PACKET_READ(ReadBool, bool, IsOnGround); - m_Client->HandlePlayerLook(Rotation, Pitch, IsOnGround); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePlayerMoveLook(void) -{ - HANDLE_PACKET_READ(ReadBEDouble, double, PosX); - HANDLE_PACKET_READ(ReadBEDouble, double, PosY); - HANDLE_PACKET_READ(ReadBEDouble, double, Stance); - HANDLE_PACKET_READ(ReadBEDouble, double, PosZ); - HANDLE_PACKET_READ(ReadBEFloat, float, Rotation); - HANDLE_PACKET_READ(ReadBEFloat, float, Pitch); - HANDLE_PACKET_READ(ReadBool, bool, IsOnGround); - // LOGD("Recv PML: {%0.2f, %0.2f, %0.2f}, Stance %0.2f, Gnd: %d", PosX, PosY, PosZ, Stance, IsOnGround ? 1 : 0); - m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Stance, Rotation, Pitch, IsOnGround); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePlayerOnGround(void) -{ - HANDLE_PACKET_READ(ReadBool, bool, IsOnGround); - // TODO: m_Client->HandleFlying(IsOnGround); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePlayerPosition(void) -{ - HANDLE_PACKET_READ(ReadBEDouble, double, PosX); - HANDLE_PACKET_READ(ReadBEDouble, double, PosY); - HANDLE_PACKET_READ(ReadBEDouble, double, Stance); - HANDLE_PACKET_READ(ReadBEDouble, double, PosZ); - HANDLE_PACKET_READ(ReadBool, bool, IsOnGround); - m_Client->HandlePlayerPos(PosX, PosY, PosZ, Stance, IsOnGround); - return PARSE_OK; -} - - - - - -int cProtocol125::ParsePluginMessage(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ChannelName); - HANDLE_PACKET_READ(ReadBEShort, short, Length); - AString Data; - if (!m_ReceivedData.ReadString(Data, (size_t)Length)) - { - m_ReceivedData.CheckValid(); - return PARSE_INCOMPLETE; - } - m_ReceivedData.CheckValid(); - - // TODO: Process the data - LOGD("Received %d bytes of plugin data on channel \"%s\".", Length, ChannelName.c_str()); - - return PARSE_OK; -} - - - - - -int cProtocol125::ParseRespawn(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, Dimension); - HANDLE_PACKET_READ(ReadChar, char, Difficulty); - HANDLE_PACKET_READ(ReadChar, char, CreativeMode); - HANDLE_PACKET_READ(ReadBEShort, short, WorldHeight); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, LevelType); - m_Client->HandleRespawn(); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseSlotSelected(void) -{ - HANDLE_PACKET_READ(ReadBEShort, short, SlotNum); - m_Client->HandleSlotSelected(SlotNum); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseUpdateSign(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, BlockX); - HANDLE_PACKET_READ(ReadBEShort, short, BlockY); - HANDLE_PACKET_READ(ReadBEInt, int, BlockZ); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line1); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line2); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line3); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line4); - m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseUseEntity(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, SourceEntityID); - HANDLE_PACKET_READ(ReadBEInt, int, TargetEntityID); - HANDLE_PACKET_READ(ReadBool, bool, IsLeftClick); - m_Client->HandleUseEntity(TargetEntityID, IsLeftClick); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseEnchantItem(void) -{ - HANDLE_PACKET_READ(ReadByte, Byte, WindowID); - HANDLE_PACKET_READ(ReadByte, Byte, Enchantment); - - m_Client->HandleEnchantItem(WindowID, Enchantment); - - return PARSE_OK; -} - - - - - -int cProtocol125::ParseWindowClick(void) -{ - HANDLE_PACKET_READ(ReadChar, char, WindowID); - HANDLE_PACKET_READ(ReadBEShort, short, SlotNum); - HANDLE_PACKET_READ(ReadBool, bool, IsRightClick); - HANDLE_PACKET_READ(ReadBEShort, short, TransactionID); - HANDLE_PACKET_READ(ReadBool, bool, IsShiftPressed); - cItem HeldItem; - int res = ParseItem(HeldItem); - if (res < 0) - { - return res; - } - - // Convert IsShiftPressed, IsRightClick, SlotNum and HeldItem into eClickAction used in the newer protocols: - eClickAction Action; - if (IsRightClick) - { - if (IsShiftPressed) - { - Action = caShiftRightClick; - } - else - { - if (SlotNum == -999) - { - Action = (HeldItem.IsEmpty()) ? caRightClickOutsideHoldNothing : caRightClickOutside; - } - else - { - Action = caRightClick; - } - } - } - else - { - // IsLeftClick - if (IsShiftPressed) - { - Action = caShiftLeftClick; - } - else - { - if (SlotNum == -999) - { - Action = (HeldItem.IsEmpty()) ? caLeftClickOutsideHoldNothing : caRightClickOutside; - } - else - { - Action = caLeftClick; - } - } - } - m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem); - return PARSE_OK; -} - - - - - -int cProtocol125::ParseWindowClose(void) -{ - HANDLE_PACKET_READ(ReadChar, char, WindowID); - m_Client->HandleWindowClose(WindowID); - return PARSE_OK; -} - - - - - -void cProtocol125::SendPreChunk(int a_ChunkX, int a_ChunkZ, bool a_ShouldLoad) -{ - WriteByte(PACKET_PRE_CHUNK); - WriteInt (a_ChunkX); - WriteInt (a_ChunkZ); - WriteBool(a_ShouldLoad); - Flush(); -} - - - - - -void cProtocol125::SendWindowSlots(char a_WindowID, int a_NumItems, const cItem * a_Items) -{ - WriteByte (PACKET_INVENTORY_WHOLE); - WriteChar (a_WindowID); - WriteShort((short)a_NumItems); - - for (int j = 0; j < a_NumItems; j++) - { - WriteItem(a_Items[j]); - } - Flush(); -} - - - - - -void cProtocol125::WriteItem(const cItem & a_Item) -{ - short ItemType = a_Item.m_ItemType; - ASSERT(ItemType >= -1); // Check validity of packets in debug runtime - if (ItemType <= 0) - { - // Fix, to make sure no invalid values are sent. - ItemType = -1; - } - - WriteShort(ItemType); - if (a_Item.IsEmpty()) - { - return; - } - - WriteChar (a_Item.m_ItemCount); - WriteShort(a_Item.m_ItemDamage); - - if (cItem::IsEnchantable(a_Item.m_ItemType)) - { - // TODO: Implement enchantments - WriteShort(-1); - } -} - - - - - -int cProtocol125::ParseItem(cItem & a_Item) -{ - HANDLE_PACKET_READ(ReadBEShort, short, ItemType); - - if (ItemType <= -1) - { - a_Item.Empty(); - return PARSE_OK; - } - a_Item.m_ItemType = ItemType; - - HANDLE_PACKET_READ(ReadChar, char, ItemCount); - HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); - a_Item.m_ItemCount = ItemCount; - a_Item.m_ItemDamage = ItemDamage; - if (ItemCount <= 0) - { - a_Item.Empty(); - } - - if (!cItem::IsEnchantable(ItemType)) - { - return PARSE_OK; - } - - HANDLE_PACKET_READ(ReadBEShort, short, EnchantNumBytes); - - if (EnchantNumBytes <= 0) - { - return PARSE_OK; - } - - // TODO: Enchantment not implemented yet! - if (!m_ReceivedData.SkipRead((size_t)EnchantNumBytes)) - { - return PARSE_INCOMPLETE; - } - - return PARSE_OK; -} - - - - - -void cProtocol125::WriteCommonMetadata(const cEntity & a_Entity) -{ - Byte CommonMetadata = 0; - - if (a_Entity.IsOnFire()) - { - CommonMetadata |= 0x1; - } - if (a_Entity.IsCrouched()) - { - CommonMetadata |= 0x2; - } - if (a_Entity.IsRiding()) - { - CommonMetadata |= 0x4; - } - if (a_Entity.IsSprinting()) - { - CommonMetadata |= 0x8; - } - if (a_Entity.IsRclking()) - { - CommonMetadata |= 0x10; - } - if (a_Entity.IsInvisible()) - { - CommonMetadata |= 0x20; - } - - WriteByte(0x0); - WriteByte(CommonMetadata); -} - - - - - -void cProtocol125::WriteEntityMetadata(const cEntity & a_Entity) -{ - if (a_Entity.IsMinecart()) - { - WriteByte(0x51); - // No idea how Mojang makes their carts shakey shakey, so here is a complicated one-liner expression that does something similar - WriteInt( (((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * ((const cMinecart &)a_Entity).LastDamage()) * 4); - WriteByte(0x52); - WriteInt(1); // Shaking direction, doesn't seem to affect anything - WriteByte(0x73); - WriteFloat((float)(((const cMinecart &)a_Entity).LastDamage() + 10)); // Damage taken / shake effect multiplyer - - if (((cMinecart &)a_Entity).GetPayload() == cMinecart::mpFurnace) - { - WriteByte(0x10); - WriteByte(((const cMinecartWithFurnace &)a_Entity).IsFueled() ? 1 : 0); // Fueled? - } - } - else if ((a_Entity.IsProjectile() && ((cProjectileEntity &)a_Entity).GetProjectileKind() == cProjectileEntity::pkArrow)) - { - WriteByte(0x10); - WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); // Critical hitting arrow? - } -} - - - - - -void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) -{ - switch (a_Mob.GetMobType()) - { - case mtCreeper: - { - WriteByte(0x10); - WriteChar(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up? - WriteByte(0x11); - WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); // Lightning-charged? - break; - } - case mtBat: - { - WriteByte(0x10); - WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); // Upside down? - break; - } - case mtPig: - { - WriteByte(0x10); - WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); // Saddled? - break; - } - case mtVillager: - { - WriteByte(0x50); - WriteInt(((const cVillager &)a_Mob).GetVilType()); // What sort of TESTIFICATE? - break; - } - case mtZombie: - { - WriteByte(0xC); - WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); // Baby zombie? - WriteByte(0xD); - WriteByte(((const cZombie &)a_Mob).IsVillagerZombie() ? 1 : 0); // Converted zombie? - WriteByte(0xE); - WriteByte(((const cZombie &)a_Mob).IsConverting() ? 1 : 0); // Converted-but-converting-back zombllager? - break; - } - case mtGhast: - { - WriteByte(0x10); - WriteByte(((const cGhast &)a_Mob).IsCharging()); // About to spit a flameball? - break; - } - case mtWolf: - { - Byte WolfStatus = 0; - if (((const cWolf &)a_Mob).IsSitting()) - { - WolfStatus |= 0x1; - } - if (((const cWolf &)a_Mob).IsAngry()) - { - WolfStatus |= 0x2; - } - if (((const cWolf &)a_Mob).IsTame()) - { - WolfStatus |= 0x4; - } - WriteByte(0x10); - WriteByte(WolfStatus); - - WriteByte(0x72); - WriteFloat((float)(a_Mob.GetHealth())); // Tail health-o-meter (only shown when tamed, by the way) - WriteByte(0x13); - WriteByte(((const cWolf &)a_Mob).IsBegging() ? 1 : 0); // Ultra cute mode? - break; - } - case mtSheep: - { - // [1](1111) - // [] = Is sheared? () = Color, from 0 to 15 - - WriteByte(0x10); - Byte SheepMetadata = 0; - SheepMetadata = (Byte)((const cSheep &)a_Mob).GetFurColor(); - - if (((const cSheep &)a_Mob).IsSheared()) - { - SheepMetadata |= 0x16; - } - WriteByte(SheepMetadata); - break; - } - case mtEnderman: - { - WriteByte(0x10); - WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); // Block that he stole from your house - WriteByte(0x11); - WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); // Meta of block that he stole from your house - WriteByte(0x12); - WriteByte(((const cEnderman &)a_Mob).IsScreaming() ? 1 : 0); // Screaming at your face? - break; - } - case mtSkeleton: - { - WriteByte(0xD); - WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); // It's a skeleton, but it's not - break; - } - case mtWitch: - { - WriteByte(0x15); - WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything - break; - } - case mtWither: - { - WriteByte(0x54); // Int at index 20 - WriteInt((Int32)((const cWither &)a_Mob).GetWitherInvulnerableTicks()); - WriteByte(0x66); // Float at index 6 - WriteFloat((float)(a_Mob.GetHealth())); - break; - } - case mtSlime: - case mtMagmaCube: - { - WriteByte(0x10); - if (a_Mob.GetMobType() == mtSlime) - { - WriteByte((Byte)((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME - } - else - { - WriteByte((Byte)((const cMagmaCube &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME - } - break; - } - case mtHorse: - { - int Flags = 0; - if (((const cHorse &)a_Mob).IsTame()) - { - Flags |= 0x2; - } - if (((const cHorse &)a_Mob).IsSaddled()) - { - Flags |= 0x4; - } - if (((const cHorse &)a_Mob).IsChested()) - { - Flags |= 0x8; - } - if (((const cHorse &)a_Mob).IsBaby()) - { - Flags |= 0x10; // IsBred flag, according to wiki.vg - don't think it does anything in multiplayer - } - if (((const cHorse &)a_Mob).IsEating()) - { - Flags |= 0x20; - } - if (((const cHorse &)a_Mob).IsRearing()) - { - Flags |= 0x40; - } - if (((const cHorse &)a_Mob).IsMthOpen()) - { - Flags |= 0x80; - } - WriteByte(0x50); - WriteInt(Flags); - - WriteByte(0x13); - WriteByte((Byte)((const cHorse &)a_Mob).GetHorseType()); // Type of horse (donkey, chestnut, etc.) - - WriteByte(0x54); - int Appearance = 0; - Appearance = ((const cHorse &)a_Mob).GetHorseColor(); // Mask FF - Appearance |= ((const cHorse &)a_Mob).GetHorseStyle() * 256; // Mask FF00, so multiply by 256 - WriteInt(Appearance); - - WriteByte(0x56); - WriteInt(((const cHorse &)a_Mob).GetHorseArmour()); // Horshey armour - break; - } - default: - { - break; - } - } -} - - - - diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h deleted file mode 100644 index 3ea116c3b..000000000 --- a/src/Protocol/Protocol125.h +++ /dev/null @@ -1,185 +0,0 @@ - -// Protocol125.h - -// Interfaces to the cProtocol125 class representing the release 1.2.5 protocol (#29) - - - - - -#pragma once - -#include "Protocol.h" -#include "../ByteBuffer.h" -#include "../Entities/Painting.h" - - - - - -class cProtocol125 : - public cProtocol -{ - typedef cProtocol super; -public: - cProtocol125(cClientHandle * a_Client); - - /// Called when client sends some data: - virtual void DataReceived(const char * a_Data, size_t a_Size) override; - - /// Sending stuff to clients (alphabetically sorted): - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendDisconnect (const AString & a_Reason) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendEntityHeadLook (const cEntity & a_Entity) override; - virtual void SendEntityLook (const cEntity & a_Entity) override; - virtual void SendEntityMetadata (const cEntity & a_Entity) override; - virtual void SendEntityProperties (const cEntity & a_Entity) override; - virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override; - virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override; - virtual void SendEntityVelocity (const cEntity & a_Entity) override; - virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override; - virtual void SendKeepAlive (int a_PingID) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendLoginSuccess (void) override; - virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override; - virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message - virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; - virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override; - virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; - virtual void SendPlayerMaxSpeed (void) override; - virtual void SendPlayerMoveLook (void) override; - virtual void SendPlayerPosition (void) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; - virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override {} // This protocol doesn't support such message - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override {} // This protocol doesn't support such message - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; - virtual void SendStatistics (const cStatManager & a_Manager) override; - virtual void SendTabCompletionResults (const AStringVector & a_Results) override; - virtual void SendTeleportEntity (const cEntity & a_Entity) override; - virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {} - virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; - virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendWeather (eWeather a_Weather) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - virtual void SendWindowClose (const cWindow & a_Window) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override; - - virtual AString GetAuthServerID(void) override; - -protected: - /// Results of packet-parsing: - enum eParseResult - { - PARSE_OK = 1, - PARSE_ERROR = -1, - PARSE_UNKNOWN = -2, - PARSE_INCOMPLETE = -3, - } ; - - cByteBuffer m_ReceivedData; ///< Buffer for the received data - - AString m_Username; ///< Stored in ParseHandshake(), compared to Login username - - /** The dimension that was last sent to a player in a Respawn or Login packet. - Used to avoid Respawning into the same dimension, which confuses the client. */ - eDimension m_LastSentDimension; - - virtual void SendData(const char * a_Data, size_t a_Size) override; - - /// Sends the Handshake packet - void SendHandshake(const AString & a_ConnectionHash); - - /// Parse the packet of the specified type from m_ReceivedData (switch into ParseXYZ()) - virtual int ParsePacket(unsigned char a_PacketType); - - // Specific packet parsers: - virtual int ParseArmAnim (void); - virtual int ParseBlockDig (void); - virtual int ParseBlockPlace (void); - virtual int ParseChat (void); - virtual int ParseCreativeInventoryAction(void); - virtual int ParseDisconnect (void); - virtual int ParseEntityAction (void); - virtual int ParseHandshake (void); - virtual int ParseKeepAlive (void); - virtual int ParseLogin (void); - virtual int ParsePing (void); - virtual int ParsePlayerAbilities (void); - virtual int ParsePlayerLook (void); - virtual int ParsePlayerMoveLook (void); - virtual int ParsePlayerOnGround (void); - virtual int ParsePlayerPosition (void); - virtual int ParsePluginMessage (void); - virtual int ParseRespawn (void); - virtual int ParseSlotSelected (void); - virtual int ParseUpdateSign (void); - virtual int ParseUseEntity (void); - virtual int ParseEnchantItem (void); - virtual int ParseWindowClick (void); - virtual int ParseWindowClose (void); - - // Utility functions: - /// Writes a "pre-chunk" packet - void SendPreChunk(int a_ChunkX, int a_ChunkZ, bool a_ShouldLoad); - - /// Writes a "set window items" packet with the specified params - void SendWindowSlots(char a_WindowID, int a_NumItems, const cItem * a_Items); - - /// Writes one item, "slot" as the protocol wiki calls it - virtual void WriteItem(const cItem & a_Item); - - /// Parses one item, "slot" as the protocol wiki calls it, from m_ReceivedData; returns the usual ParsePacket() codes - virtual int ParseItem(cItem & a_Item); - - /// Writes the COMMON entity metadata - void WriteCommonMetadata(const cEntity & a_Entity); - - /// Writes normal entity metadata - void WriteEntityMetadata(const cEntity & a_Entity); - - /// Writes mobile entity metadata - void WriteMobMetadata(const cMonster & a_Mob); -} ; - - - - diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp deleted file mode 100644 index 63a15c082..000000000 --- a/src/Protocol/Protocol132.cpp +++ /dev/null @@ -1,880 +0,0 @@ - -// Protocol132.cpp - -// Implements the cProtocol132 class representing the release 1.3.2 protocol (#39) - -#include "Globals.h" -#include "ChunkDataSerializer.h" -#include "Protocol132.h" -#include "../Root.h" -#include "../Server.h" -#include "../World.h" -#include "../ClientHandle.h" -#include "../Item.h" -#include "../Entities/Player.h" -#include "../Mobs/Monster.h" -#include "../UI/Window.h" -#include "../Entities/Pickup.h" -#include "../WorldStorage/FastNBT.h" -#include "../WorldStorage/EnchantmentSerializer.h" -#include "../StringCompression.h" -#include "PolarSSL++/Sha1Checksum.h" - - - - - -#define HANDLE_PACKET_READ(Proc, Type, Var) \ - Type Var; \ - { \ - if (!m_ReceivedData.Proc(Var)) \ - { \ - m_ReceivedData.CheckValid(); \ - return PARSE_INCOMPLETE; \ - } \ - m_ReceivedData.CheckValid(); \ - } - - - - - -const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... - - - - - -enum -{ - PACKET_KEEP_ALIVE = 0x00, - PACKET_LOGIN = 0x01, - PACKET_ENTITY_EQUIPMENT = 0x05, - PACKET_COMPASS = 0x06, - PACKET_PLAYER_SPAWN = 0x14, - PACKET_COLLECT_PICKUP = 0x16, - PACKET_SPAWN_MOB = 0x18, - PACKET_DESTROY_ENTITIES = 0x1d, - PACKET_CHUNK_DATA = 0x33, - PACKET_BLOCK_CHANGE = 0x35, - PACKET_BLOCK_ACTION = 0x36, - PACKET_BLOCK_BREAK_ANIM = 0x37, - PACKET_SOUND_EFFECT = 0x3e, - PACKET_SOUND_PARTICLE_EFFECT = 0x3d, - PACKET_TAB_COMPLETION = 0xcb, - PACKET_LOCALE_VIEW_DISTANCE = 0xcc, - PACKET_CLIENT_STATUSES = 0xcd, - PACKET_ENCRYPTION_KEY_RESP = 0xfc, -} ; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol132: - -cProtocol132::cProtocol132(cClientHandle * a_Client) : - super(a_Client), - m_IsEncrypted(false) -{ -} - - - - - -cProtocol132::~cProtocol132() -{ - if (!m_DataToSend.empty()) - { - LOGD("There are " SIZE_T_FMT " unsent bytes while deleting cProtocol132", m_DataToSend.size()); - } -} - - - - - -void cProtocol132::DataReceived(const char * a_Data, size_t a_Size) -{ - if (m_IsEncrypted) - { - Byte Decrypted[512]; - while (a_Size > 0) - { - size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; - m_Decryptor.ProcessData(Decrypted, (Byte *)a_Data, NumBytes); - super::DataReceived((const char *)Decrypted, NumBytes); - a_Size -= NumBytes; - a_Data += NumBytes; - } - } - else - { - super::DataReceived(a_Data, a_Size); - } -} - - - - - -void cProtocol132::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_BLOCK_ACTION); - WriteInt (a_BlockX); - WriteShort((short)a_BlockY); - WriteInt (a_BlockZ); - WriteChar (a_Byte1); - WriteChar (a_Byte2); - WriteShort(a_BlockType); - Flush(); -} - - - - - -void cProtocol132::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_BLOCK_BREAK_ANIM); - WriteInt (a_entityID); - WriteInt (a_BlockX); - WriteInt (a_BlockY); - WriteInt (a_BlockZ); - WriteChar (stage); - Flush(); -} - - - - - -void cProtocol132::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_BLOCK_CHANGE); - WriteInt (a_BlockX); - WriteByte ((unsigned char)a_BlockY); - WriteInt (a_BlockZ); - WriteShort(a_BlockType); - WriteByte (a_BlockMeta); - Flush(); -} - - - - - -void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) -{ - cCSLock Lock(m_CSPacket); - - // Pre-chunk not used in 1.3.2. Finally. - - // Send the chunk data: - AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ); - WriteByte(PACKET_CHUNK_DATA); - WriteInt (a_ChunkX); - WriteInt (a_ChunkZ); - SendData(Serialized.data(), Serialized.size()); - Flush(); -} - - - - - -void cProtocol132::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_COLLECT_PICKUP); - WriteInt (a_Entity.GetUniqueID()); - WriteInt (a_Player.GetUniqueID()); - Flush(); -} - - - - - -void cProtocol132::SendDestroyEntity(const cEntity & a_Entity) -{ - if (a_Entity.GetUniqueID() == m_Client->GetPlayer()->GetUniqueID()) - { - // Do not send "destroy self" to the client, the client would crash (FS #254) - return; - } - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_DESTROY_ENTITIES); - WriteByte(1); // entity count - WriteInt (a_Entity.GetUniqueID()); - Flush(); -} - - - - - -void cProtocol132::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_ENTITY_EQUIPMENT); - WriteInt (a_Entity.GetUniqueID()); - WriteShort(a_SlotNum); - WriteItem (a_Item); - Flush(); -} - - - - - -void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_LOGIN); - WriteInt (a_Player.GetUniqueID()); // EntityID of the player - WriteString("default"); // Level type - WriteByte ((Byte)a_Player.GetGameMode()); - WriteByte ((Byte)(a_World.GetDimension())); - WriteByte (2); // TODO: Difficulty - WriteByte (0); // Unused, used to be world height - WriteByte (8); // Client list width or something - Flush(); - m_LastSentDimension = a_World.GetDimension(); - SendCompass(a_World); -} - - - - - -void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player) -{ - const cItem & HeldItem = a_Player.GetEquippedItem(); - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PLAYER_SPAWN); - WriteInt (a_Player.GetUniqueID()); - if (a_Player.HasCustomName()) - { - WriteString(a_Player.GetCustomName()); - } - else - { - WriteString(a_Player.GetName()); - } - WriteInt ((int)(a_Player.GetPosX() * 32)); - WriteInt ((int)(a_Player.GetPosY() * 32)); - WriteInt ((int)(a_Player.GetPosZ() * 32)); - WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); - WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); - WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); - // Player metadata: just use a default metadata value, since the client doesn't like starting without any metadata: - WriteByte (0); // Index 0, byte (flags) - WriteByte (0); // Flags, empty - WriteByte (0x7f); // End of metadata - Flush(); -} - - - - - -void cProtocol132::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_SOUND_EFFECT); - WriteString (a_SoundName); - WriteInt ((int)(a_X * 8.0)); - WriteInt ((int)(a_Y * 8.0)); - WriteInt ((int)(a_Z * 8.0)); - WriteFloat (a_Volume); - WriteChar ((char)(a_Pitch * 63.0f)); - Flush(); -} - - - - - -void cProtocol132::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SOUND_PARTICLE_EFFECT); - WriteInt (a_EffectID); - WriteInt (a_SrcX); - WriteByte((Byte)a_SrcY); - WriteInt (a_SrcZ); - WriteInt (a_Data); - Flush(); -} - - - - - -void cProtocol132::SendSpawnMob(const cMonster & a_Mob) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_SPAWN_MOB); - WriteInt (a_Mob.GetUniqueID()); - WriteByte ((Byte)a_Mob.GetMobType()); - WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32)); - WriteByte ((Byte)((a_Mob.GetYaw() / 360.f) * 256)); - WriteByte ((Byte)((a_Mob.GetPitch() / 360.f) * 256)); - WriteByte ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256)); - WriteShort ((short)(a_Mob.GetSpeedX() * 400)); - WriteShort ((short)(a_Mob.GetSpeedY() * 400)); - WriteShort ((short)(a_Mob.GetSpeedZ() * 400)); - - WriteCommonMetadata(a_Mob); - WriteMobMetadata(a_Mob); - WriteByte(0x7f); - - Flush(); -} - - - - - -void cProtocol132::SendTabCompletionResults(const AStringVector & a_Results) -{ - if (a_Results.empty()) - { - // No results to send - return; - } - - AString Serialized(a_Results[0]); - for (AStringVector::const_iterator itr = a_Results.begin() + 1, end = a_Results.end(); itr != end; ++itr) - { - Serialized.push_back(0); - Serialized.append(*itr); - } // for itr - a_Results[] - - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_TAB_COMPLETION); - WriteString(Serialized); - Flush(); -} - - - - - -void cProtocol132::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -{ - // Unloading the chunk is done by sending a "map chunk" packet - // with IncludeInitialize set to true and primary bitmap set to 0: - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_CHUNK_DATA); - WriteInt (a_ChunkX); - WriteInt (a_ChunkZ); - WriteBool(true); // IncludeInitialize - WriteShort(0); // Primary bitmap - WriteShort(0); // Add bitmap - WriteInt(0); - Flush(); -} - - - - - -void cProtocol132::SendWholeInventory(const cWindow & a_Window) -{ - // 1.3.2 requires player inventory slots to be sent as SetSlot packets, - // otherwise it sometimes fails to update the window - - // Send the entire window: - super::SendWholeInventory(a_Window); - - // Send the player inventory and hotbar: - cPlayer * Player = m_Client->GetPlayer(); - const cInventory & Inventory = Player->GetInventory(); - int BaseOffset = a_Window.GetNumSlots() - (cInventory::invNumSlots - cInventory::invInventoryOffset); // Number of non-inventory slots - char WindowID = a_Window.GetWindowID(); - for (short i = 0; i < cInventory::invInventoryCount; i++) - { - SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetInventorySlot(i)); - } // for i - Inventory[] - BaseOffset += cInventory::invInventoryCount; - for (short i = 0; i < cInventory::invHotbarCount; i++) - { - SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetHotbarSlot(i)); - } // for i - Hotbar[] - - // Send even the item being dragged: - SendInventorySlot(-1, -1, Player->GetDraggingItem()); -} - - - - - -AString cProtocol132::GetAuthServerID(void) -{ - // http://wiki.vg/wiki/index.php?title=Session&oldid=2615 - // Server uses SHA1 to mix ServerID, Client secret and server public key together - // The mixing is done in StartEncryption, the result is in m_AuthServerID - - return m_AuthServerID; -} - - - - - -int cProtocol132::ParsePacket(unsigned char a_PacketType) -{ - switch (a_PacketType) - { - default: return super::ParsePacket(a_PacketType); // off-load previously known packets into cProtocol125 - case PACKET_CLIENT_STATUSES: return ParseClientStatuses(); - case PACKET_ENCRYPTION_KEY_RESP: return ParseEncryptionKeyResponse(); - case PACKET_LOCALE_VIEW_DISTANCE: return ParseLocaleViewDistance(); - case PACKET_TAB_COMPLETION: return ParseTabCompletion(); - } -} - - - - - -int cProtocol132::ParseBlockPlace(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, PosX); - HANDLE_PACKET_READ(ReadByte, Byte, PosY); - HANDLE_PACKET_READ(ReadBEInt, int, PosZ); - HANDLE_PACKET_READ(ReadChar, char, BlockFace); - - cItem HeldItem; - int res = ParseItem(HeldItem); - if (res < 0) - { - return res; - } - - HANDLE_PACKET_READ(ReadChar, char, CursorX); - HANDLE_PACKET_READ(ReadChar, char, CursorY); - HANDLE_PACKET_READ(ReadChar, char, CursorZ); - - m_Client->HandleRightClick(PosX, PosY, PosZ, static_cast(BlockFace), CursorX, CursorY, CursorZ, HeldItem); - return PARSE_OK; -} - - - - - -int cProtocol132::ParseHandshake(void) -{ - HANDLE_PACKET_READ(ReadByte, Byte, ProtocolVersion); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ServerHost); - HANDLE_PACKET_READ(ReadBEInt, int, ServerPort); - m_Username = Username; - - if (!m_Client->HandleHandshake( m_Username)) - { - return PARSE_OK; // Player is not allowed into the server - } - - // Send a 0xfd Encryption Key Request http://wiki.vg/Protocol#0xFD - SendEncryptionKeyRequest(); - - return PARSE_OK; -} - - - - - -int cProtocol132::ParseClientStatuses(void) -{ - HANDLE_PACKET_READ(ReadByte, Byte, Status); - if ((Status & 1) == 0) - { - m_Client->HandleLogin(39, m_Username); - } - else - { - m_Client->HandleRespawn(); - } - return PARSE_OK; -} - - - - - -int cProtocol132::ParseEncryptionKeyResponse(void) -{ - // Read the encryption key: - HANDLE_PACKET_READ(ReadBEShort, short, EncKeyLength); - if (EncKeyLength > MAX_ENC_LEN) - { - LOGD("Too long encryption key"); - m_Client->Kick("Hacked client"); - return PARSE_OK; - } - AString EncKey; - if (!m_ReceivedData.ReadString(EncKey, (size_t)EncKeyLength)) - { - return PARSE_INCOMPLETE; - } - - // Read the encryption nonce: - HANDLE_PACKET_READ(ReadBEShort, short, EncNonceLength); - AString EncNonce; - if (!m_ReceivedData.ReadString(EncNonce, (size_t)EncNonceLength)) - { - return PARSE_INCOMPLETE; - } - if (EncNonceLength > MAX_ENC_LEN) - { - LOGD("Too long encryption nonce"); - m_Client->Kick("Hacked client"); - return PARSE_OK; - } - - HandleEncryptionKeyResponse(EncKey, EncNonce); - return PARSE_OK; -} - - - - - -int cProtocol132::ParseLocaleViewDistance(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Locale); - HANDLE_PACKET_READ(ReadChar, char, ViewDistance); - HANDLE_PACKET_READ(ReadChar, char, ChatFlags); - HANDLE_PACKET_READ(ReadChar, char, ClientDifficulty); - m_Client->SetLocale(Locale); - // TODO: m_Client->HandleViewDistance(ViewDistance); - // TODO: m_Client->HandleChatFlags(ChatFlags); - // Ignoring client difficulty - return PARSE_OK; -} - - - - - -int cProtocol132::ParseLogin(void) -{ - // Login packet not used in 1.3.2 - return PARSE_ERROR; -} - - - - - -int cProtocol132::ParsePlayerAbilities(void) -{ - HANDLE_PACKET_READ(ReadBool, bool, Flags); - HANDLE_PACKET_READ(ReadChar, char, FlyingSpeed); - HANDLE_PACKET_READ(ReadChar, char, WalkingSpeed); - // TODO: m_Client->HandlePlayerAbilities(...); - return PARSE_OK; -} - - - - - -int cProtocol132::ParseTabCompletion(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Text); - m_Client->HandleTabCompletion(Text); - return PARSE_OK; -} - - - - - -void cProtocol132::SendData(const char * a_Data, size_t a_Size) -{ - m_DataToSend.append(a_Data, a_Size); -} - - - - - -void cProtocol132::Flush(void) -{ - ASSERT(m_CSPacket.IsLockedByCurrentThread()); // Did all packets lock the CS properly? - - if (m_DataToSend.empty()) - { - LOGD("Flushing empty"); - return; - } - const char * Data = m_DataToSend.data(); - size_t Size = m_DataToSend.size(); - if (m_IsEncrypted) - { - Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) - while (Size > 0) - { - size_t NumBytes = (Size > sizeof(Encrypted)) ? sizeof(Encrypted) : Size; - m_Encryptor.ProcessData(Encrypted, (Byte *)Data, NumBytes); - super::SendData((const char *)Encrypted, NumBytes); - Size -= NumBytes; - Data += NumBytes; - } - } - else - { - super::SendData(Data, Size); - } - m_DataToSend.clear(); -} - - - - - -void cProtocol132::WriteItem(const cItem & a_Item) -{ - short ItemType = a_Item.m_ItemType; - ASSERT(ItemType >= -1); // Check validity of packets in debug runtime - if (ItemType <= 0) - { - // Fix, to make sure no invalid values are sent. - ItemType = -1; - } - - if (a_Item.IsEmpty()) - { - WriteShort(-1); - return; - } - - WriteShort(ItemType); - WriteChar (a_Item.m_ItemCount); - WriteShort(a_Item.m_ItemDamage); - - if (a_Item.m_Enchantments.IsEmpty()) - { - WriteShort(-1); - return; - } - - // Send the enchantments: - cFastNBTWriter Writer; - const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; - EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); - Writer.Finish(); - AString Compressed; - CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); - WriteShort((short)Compressed.size()); - SendData(Compressed.data(), Compressed.size()); -} - - - - - -int cProtocol132::ParseItem(cItem & a_Item) -{ - HANDLE_PACKET_READ(ReadBEShort, short, ItemType); - - if (ItemType <= -1) - { - a_Item.Empty(); - return PARSE_OK; - } - a_Item.m_ItemType = ItemType; - - HANDLE_PACKET_READ(ReadChar, char, ItemCount); - HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); - a_Item.m_ItemCount = ItemCount; - a_Item.m_ItemDamage = ItemDamage; - if (ItemCount <= 0) - { - a_Item.Empty(); - } - - HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength); - if (MetadataLength <= 0) - { - return PARSE_OK; - } - - // Read the metadata - AString Metadata; - Metadata.resize((size_t)MetadataLength); - if (!m_ReceivedData.ReadBuf((void *)Metadata.data(), (size_t)MetadataLength)) - { - return PARSE_INCOMPLETE; - } - - return ParseItemMetadata(a_Item, Metadata); -} - - - - - -int cProtocol132::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) -{ - // Uncompress the GZIPped data: - AString Uncompressed; - if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK) - { - AString HexDump; - CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); - LOG("Cannot unGZIP item metadata:\n%s", HexDump.c_str()); - return PARSE_ERROR; - } - - // Parse into NBT: - cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); - if (!NBT.IsValid()) - { - AString HexDump; - CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16); - LOG("Cannot parse NBT item metadata:\n%s", HexDump.c_str()); - return PARSE_ERROR; - } - - // Load enchantments from the NBT: - for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) - { - if ( - (NBT.GetType(tag) == TAG_List) && - ( - (NBT.GetName(tag) == "ench") || - (NBT.GetName(tag) == "StoredEnchantments") - ) - ) - { - EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); - } - } - - return PARSE_OK; -} - - - - - -void cProtocol132::SendCompass(const cWorld & a_World) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_COMPASS); - WriteInt((int)(a_World.GetSpawnX())); - WriteInt((int)(a_World.GetSpawnY())); - WriteInt((int)(a_World.GetSpawnZ())); - Flush(); -} - - - - - -void cProtocol132::SendEncryptionKeyRequest(void) -{ - cCSLock Lock(m_CSPacket); - cServer * Server = cRoot::Get()->GetServer(); - WriteByte(0xfd); - WriteString(Server->GetServerID()); - const AString & PublicKeyDER = Server->GetPublicKeyDER(); - WriteShort((short)(PublicKeyDER.size())); - SendData(PublicKeyDER.data(), PublicKeyDER.size()); - WriteShort(4); - WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :) - Flush(); -} - - - - - -void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce) -{ - // Decrypt EncNonce using privkey - cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); - - Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; - int res = rsaDecryptor.Decrypt((const Byte *)a_EncNonce.data(), a_EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); - if (res != 4) - { - LOGD("Bad nonce length"); - m_Client->Kick("Hacked client"); - return; - } - if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) - { - LOGD("Bad nonce value"); - m_Client->Kick("Hacked client"); - return; - } - - // Decrypt the symmetric encryption key using privkey: - Byte DecryptedKey[MAX_ENC_LEN]; - res = rsaDecryptor.Decrypt((const Byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); - if (res != 16) - { - LOGD("Bad key length"); - m_Client->Kick("Hacked client"); - return; - } - - { - // Send encryption key response: - cCSLock Lock(m_CSPacket); - WriteByte(0xfc); - WriteShort(0); - WriteShort(0); - Flush(); - } - - #ifdef _DEBUG - AString DecryptedKeyHex; - CreateHexDump(DecryptedKeyHex, DecryptedKey, res, 16); - LOGD("Received encryption key, %d bytes:\n%s", res, DecryptedKeyHex.c_str()); - #endif - - StartEncryption(DecryptedKey); - return; -} - - - - - -void cProtocol132::StartEncryption(const Byte * a_Key) -{ - m_Encryptor.Init(a_Key, a_Key); - m_Decryptor.Init(a_Key, a_Key); - m_IsEncrypted = true; - - // Prepare the m_AuthServerID: - cSha1Checksum Checksum; - cServer * Server = cRoot::Get()->GetServer(); - AString ServerID = Server->GetServerID(); - Checksum.Update((const Byte *)ServerID.c_str(), ServerID.length()); - Checksum.Update(a_Key, 16); - Checksum.Update((const Byte *)Server->GetPublicKeyDER().data(), Server->GetPublicKeyDER().size()); - Byte Digest[20]; - Checksum.Finalize(Digest); - cSha1Checksum::DigestToJava(Digest, m_AuthServerID); -} - - - - diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h deleted file mode 100644 index 1124a7253..000000000 --- a/src/Protocol/Protocol132.h +++ /dev/null @@ -1,115 +0,0 @@ - -// Protocol132.h - -// Interfaces to the cProtocol132 class representing the release 1.3.2 protocol (#39) - - - - - -#pragma once - -#include "Protocol125.h" - -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable:4127) - #pragma warning(disable:4189) - #pragma warning(disable:4231) - #pragma warning(disable:4244) - #pragma warning(disable:4702) -#endif - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - -#include "PolarSSL++/AesCfb128Decryptor.h" -#include "PolarSSL++/AesCfb128Encryptor.h" - - - - - -class cProtocol132 : - public cProtocol125 -{ - typedef cProtocol125 super; -public: - - cProtocol132(cClientHandle * a_Client); - virtual ~cProtocol132(); - - /// Called when client sends some data: - virtual void DataReceived(const char * a_Data, size_t a_Size) override; - - // Sending commands (alphabetically sorted): - virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; - virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; - virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; - virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; - virtual void SendDestroyEntity (const cEntity & a_Entity) override; - virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; - virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; - virtual void SendPlayerSpawn (const cPlayer & a_Player) override; - virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendTabCompletionResults(const AStringVector & a_Results) override; - virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendWholeInventory (const cWindow & a_Window) override; - - virtual AString GetAuthServerID(void) override; - - /// Handling of the additional packets: - virtual int ParsePacket(unsigned char a_PacketType) override; - - // Modified packets: - virtual int ParseBlockPlace (void) override; - virtual int ParseHandshake (void) override; - virtual int ParseLogin (void) override; - virtual int ParsePlayerAbilities(void) override; - - // New packets: - virtual int ParseClientStatuses (void); - virtual int ParseEncryptionKeyResponse(void); - virtual int ParseLocaleViewDistance (void); - virtual int ParseTabCompletion (void); - -protected: - bool m_IsEncrypted; - - cAesCfb128Decryptor m_Decryptor; - cAesCfb128Encryptor m_Encryptor; - - AString m_DataToSend; - - /// The ServerID used for session authentication; set in StartEncryption(), used in GetAuthServerID() - AString m_AuthServerID; - - virtual void SendData(const char * a_Data, size_t a_Size) override; - - // DEBUG: - virtual void Flush(void) override; - - // Items in slots are sent differently - virtual void WriteItem(const cItem & a_Item) override; - virtual int ParseItem(cItem & a_Item) override; - - /// Parses the metadata that may come with the item. - int ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); - - virtual void SendCompass(const cWorld & a_World); - virtual void SendEncryptionKeyRequest(void); - - /// Decrypts the key and nonce, checks nonce, starts the symmetric encryption - void HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce); - - /// Starts the symmetric encryption with the specified key; also sets m_AuthServerID - void StartEncryption(const Byte * a_Key); -} ; - - - - diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp deleted file mode 100644 index d33314a2f..000000000 --- a/src/Protocol/Protocol14x.cpp +++ /dev/null @@ -1,265 +0,0 @@ - -// Protocol14x.cpp - -/* -Implements the 1.4.x protocol classes representing these protocols: -- cProtocol142: - - release 1.4.2 protocol (#47) - - release 1.4.4 protocol (#49) - the same protocol class is used, because the only difference is in a packet that MCServer doesn't implement yet (ITEM_DATA) - - release 1.4.5 protocol (same as 1.4.4) -- cProtocol146: - - release 1.4.6 protocol (#51) -*/ - -#include "Globals.h" -#include "Protocol14x.h" -#include "../Root.h" -#include "../Server.h" -#include "../ClientHandle.h" -#include "../Item.h" -#include "ChunkDataSerializer.h" -#include "../Entities/Player.h" -#include "../Mobs/Monster.h" -#include "../UI/Window.h" -#include "../Entities/Pickup.h" -#include "../Entities/FallingBlock.h" - -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable:4127) - #pragma warning(disable:4244) - #pragma warning(disable:4231) - #pragma warning(disable:4189) - #pragma warning(disable:4702) -#endif - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - - -#define HANDLE_PACKET_READ(Proc, Type, Var) \ - Type Var; \ - { \ - if (!m_ReceivedData.Proc(Var)) \ - { \ - m_ReceivedData.CheckValid(); \ - return PARSE_INCOMPLETE; \ - } \ - m_ReceivedData.CheckValid(); \ - } - - - - - -enum -{ - PACKET_UPDATE_TIME = 0x04, - PACKET_PICKUP_SPAWN = 0x15, - PACKET_SPAWN_OBJECT = 0x17, - PACKET_ENTITY_METADATA = 0x28, - PACKET_SOUND_PARTICLE_EFFECT = 0x3d -} ; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol142: - -cProtocol142::cProtocol142(cClientHandle * a_Client) : - super(a_Client) -{ -} - - - - - -int cProtocol142::ParseLocaleViewDistance(void) -{ - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Locale); - HANDLE_PACKET_READ(ReadChar, char, ViewDistance); - HANDLE_PACKET_READ(ReadChar, char, ChatFlags); - HANDLE_PACKET_READ(ReadChar, char, ClientDifficulty); - HANDLE_PACKET_READ(ReadChar, char, ShouldShowCape); // <-- new in 1.4.2 - m_Client->SetLocale(Locale); - // TODO: m_Client->HandleViewDistance(ViewDistance); - // TODO: m_Client->HandleChatFlags(ChatFlags); - // Ignoring client difficulty - return PARSE_OK; -} - - - - - -void cProtocol142::SendPickupSpawn(const cPickup & a_Pickup) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_PICKUP_SPAWN); - WriteInt (a_Pickup.GetUniqueID()); - WriteItem (a_Pickup.GetItem()); - WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32)); - WriteChar((char)(a_Pickup.GetSpeedX() * 8)); - WriteChar((char)(a_Pickup.GetSpeedY() * 8)); - WriteChar((char)(a_Pickup.GetSpeedZ() * 8)); - Flush(); -} - - - - - -void cProtocol142::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SOUND_PARTICLE_EFFECT); - WriteInt (a_EffectID); - WriteInt (a_SrcX); - WriteByte((Byte)a_SrcY); - WriteInt (a_SrcZ); - WriteInt (a_Data); - WriteBool(0); - Flush(); -} - - - - - -void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_UPDATE_TIME); - WriteInt64(a_WorldAge); - WriteInt64(a_TimeOfDay); - Flush(); -} - - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol146: - -cProtocol146::cProtocol146(cClientHandle * a_Client) : - super(a_Client) -{ -} - - - - - -void cProtocol146::SendPickupSpawn(const cPickup & a_Pickup) -{ - ASSERT(!a_Pickup.GetItem().IsEmpty()); - - cCSLock Lock(m_CSPacket); - - // Send a SPAWN_OBJECT packet for the base entity: - WriteByte(PACKET_SPAWN_OBJECT); - WriteInt (a_Pickup.GetUniqueID()); - WriteByte(0x02); - WriteInt ((int)(a_Pickup.GetPosX() * 32)); - WriteInt ((int)(a_Pickup.GetPosY() * 32)); - WriteInt ((int)(a_Pickup.GetPosZ() * 32)); - WriteInt (1); - WriteShort((short)(a_Pickup.GetSpeedX() * 32)); - WriteShort((short)(a_Pickup.GetSpeedY() * 32)); - WriteShort((short)(a_Pickup.GetSpeedZ() * 32)); - WriteByte(0); - WriteByte(0); - - // Send a ENTITY_METADATA packet with the slot info: - WriteByte(PACKET_ENTITY_METADATA); - WriteInt(a_Pickup.GetUniqueID()); - WriteByte(0xaa); // a slot value at index 10 - WriteItem(a_Pickup.GetItem()); - WriteByte(0x7f); // End of metadata - Flush(); -} - - - - - -void cProtocol146::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) -{ - // Send a spawn object / vehicle packet - cCSLock Lock(m_CSPacket); - - WriteByte(PACKET_SPAWN_OBJECT); - WriteInt (a_FallingBlock.GetUniqueID()); - WriteByte(70); - WriteInt ((int)(a_FallingBlock.GetPosX() * 32)); - WriteInt ((int)(a_FallingBlock.GetPosY() * 32)); - WriteInt ((int)(a_FallingBlock.GetPosZ() * 32)); - WriteByte (0); // Pitch - WriteByte (0); // Yaw - WriteInt (a_FallingBlock.GetBlockType()); // data indicator = blocktype - WriteShort((short)(a_FallingBlock.GetSpeedX() * 400)); - WriteShort((short)(a_FallingBlock.GetSpeedY() * 400)); - WriteShort((short)(a_FallingBlock.GetSpeedZ() * 400)); - Flush(); -} - - - - - -void cProtocol146::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SPAWN_OBJECT); - WriteInt (a_Entity.GetUniqueID()); - WriteChar(a_ObjectType); - WriteInt ((int)(a_Entity.GetPosX() * 32)); - WriteInt ((int)(a_Entity.GetPosY() * 32)); - WriteInt ((int)(a_Entity.GetPosZ() * 32)); - WriteByte(a_Pitch); - WriteByte(a_Yaw); - WriteInt (a_ObjectData); - if (a_ObjectData != 0) - { - WriteShort((short)(a_Entity.GetSpeedX() * 400)); - WriteShort((short)(a_Entity.GetSpeedY() * 400)); - WriteShort((short)(a_Entity.GetSpeedZ() * 400)); - } - Flush(); -} - - - - - -void cProtocol146::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_SPAWN_OBJECT); - WriteInt (a_Vehicle.GetUniqueID()); - WriteChar (a_VehicleType); - WriteInt ((int)(a_Vehicle.GetPosX() * 32)); - WriteInt ((int)(a_Vehicle.GetPosY() * 32)); - WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); - WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256)); - WriteByte ((Byte)((a_Vehicle.GetYaw() / 360.f) * 256)); - WriteInt (a_VehicleSubType); - if (a_VehicleSubType != 0) - { - WriteShort((short)(a_Vehicle.GetSpeedX() * 400)); - WriteShort((short)(a_Vehicle.GetSpeedY() * 400)); - WriteShort((short)(a_Vehicle.GetSpeedZ() * 400)); - } - Flush(); -} - - - - - diff --git a/src/Protocol/Protocol14x.h b/src/Protocol/Protocol14x.h deleted file mode 100644 index 227cc8cc7..000000000 --- a/src/Protocol/Protocol14x.h +++ /dev/null @@ -1,63 +0,0 @@ - -// Protocol14x.h - -/* -Interfaces to the 1.4.x protocol classes representing these protocols: -- cProtocol142: - - release 1.4.2 protocol (#47) - - release 1.4.4 protocol (#49) - the same protocol class is used, because the only difference is in a packet that MCServer doesn't implement yet (ITEM_DATA) - - release 1.4.5 protocol (same as 1.4.4) -- cProtocol146: - - release 1.4.6 protocol (#51) -*/ - - - - - -#pragma once - -#include "Protocol132.h" - - - - - -class cProtocol142 : - public cProtocol132 -{ - typedef cProtocol132 super; - -public: - cProtocol142(cClientHandle * a_Client); - - // Sending commands (alphabetically sorted): - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; - - // Specific packet parsers: - virtual int ParseLocaleViewDistance(void) override; -} ; - - - - - -class cProtocol146 : - public cProtocol142 -{ - typedef cProtocol142 super; - -public: - cProtocol146(cClientHandle * a_Client); - - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; -} ; - - - - diff --git a/src/Protocol/Protocol15x.cpp b/src/Protocol/Protocol15x.cpp deleted file mode 100644 index 089296fdf..000000000 --- a/src/Protocol/Protocol15x.cpp +++ /dev/null @@ -1,209 +0,0 @@ - -// Protocol15x.cpp - -/* -Implements the 1.5.x protocol classes: - - cProtocol150 - - release 1.5 protocol (#60) - - release 1.5.2 protocol (#61, no relevant changes found) -*/ - -#include "Globals.h" -#include "Protocol15x.h" -#include "../ClientHandle.h" -#include "../Item.h" -#include "../UI/Window.h" - - - - - -#define HANDLE_PACKET_READ(Proc, Type, Var) \ - Type Var; \ - { \ - if (!m_ReceivedData.Proc(Var)) \ - { \ - m_ReceivedData.CheckValid(); \ - return PARSE_INCOMPLETE; \ - } \ - m_ReceivedData.CheckValid(); \ - } - - - - - -enum -{ - PACKET_WINDOW_OPEN = 0x64, - PACKET_PARTICLE_EFFECT = 0x3F, - PACKET_SCOREBOARD_OBJECTIVE = 0xCE, - PACKET_SCORE_UPDATE = 0xCF, - PACKET_DISPLAY_OBJECTIVE = 0xD0 -} ; - - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol150: - -cProtocol150::cProtocol150(cClientHandle * a_Client) : - super(a_Client) -{ -} - - - - - -void cProtocol150::SendWindowOpen(const cWindow & a_Window) -{ - if (a_Window.GetWindowType() < 0) - { - // Do not send for inventory windows - return; - } - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_WINDOW_OPEN); - WriteByte (a_Window.GetWindowID()); - WriteByte (a_Window.GetWindowType()); - WriteString(a_Window.GetWindowTitle()); - WriteByte (a_Window.GetNumNonInventorySlots()); - WriteByte (1); // Use title - Flush(); -} - - - - - -void cProtocol150::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_PARTICLE_EFFECT); - WriteString(a_ParticleName); - WriteFloat(a_SrcX); - WriteFloat(a_SrcY); - WriteFloat(a_SrcZ); - WriteFloat(a_OffsetX); - WriteFloat(a_OffsetY); - WriteFloat(a_OffsetZ); - WriteFloat(a_ParticleData); - WriteInt(a_ParticleAmount); - Flush(); -} - - - - - -void cProtocol150::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SCOREBOARD_OBJECTIVE); - WriteString(a_Name); - WriteString(a_DisplayName); - WriteByte(a_Mode); - Flush(); -} - - - - - -void cProtocol150::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_SCORE_UPDATE); - WriteString(a_Player); - WriteByte(a_Mode); - - if (a_Mode != 1) - { - WriteString(a_Objective); - WriteInt((int) a_Score); - } - - Flush(); -} - - - - - -void cProtocol150::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_DISPLAY_OBJECTIVE); - WriteByte((int) a_Display); - WriteString(a_Objective); - Flush(); -} - - - - - -int cProtocol150::ParseWindowClick(void) -{ - HANDLE_PACKET_READ(ReadChar, char, WindowID); - HANDLE_PACKET_READ(ReadBEShort, short, SlotNum); - HANDLE_PACKET_READ(ReadByte, Byte, Button); - HANDLE_PACKET_READ(ReadBEShort, short, TransactionID); - HANDLE_PACKET_READ(ReadByte, Byte, Mode); - cItem HeldItem; - int res = ParseItem(HeldItem); - if (res < 0) - { - return res; - } - - // Convert Button, Mode, SlotNum and HeldItem into eClickAction: - eClickAction Action = caUnknown; - switch ((Mode << 8) | Button) - { - case 0x0000: Action = (SlotNum != -999) ? caLeftClick : caLeftClickOutside; break; - case 0x0001: Action = (SlotNum != -999) ? caRightClick : caRightClickOutside; break; - case 0x0100: Action = caShiftLeftClick; break; - case 0x0101: Action = caShiftRightClick; break; - case 0x0200: Action = caNumber1; break; - case 0x0201: Action = caNumber2; break; - case 0x0202: Action = caNumber3; break; - case 0x0203: Action = caNumber4; break; - case 0x0204: Action = caNumber5; break; - case 0x0205: Action = caNumber6; break; - case 0x0206: Action = caNumber7; break; - case 0x0207: Action = caNumber8; break; - case 0x0208: Action = caNumber9; break; - case 0x0300: Action = caMiddleClick; break; - case 0x0400: Action = (SlotNum == -999) ? caLeftClickOutsideHoldNothing : caDropKey; break; - case 0x0401: Action = (SlotNum == -999) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break; - case 0x0500: Action = (SlotNum == -999) ? caLeftPaintBegin : caUnknown; break; - case 0x0501: Action = (SlotNum != -999) ? caLeftPaintProgress : caUnknown; break; - case 0x0502: Action = (SlotNum == -999) ? caLeftPaintEnd : caUnknown; break; - case 0x0504: Action = (SlotNum == -999) ? caRightPaintBegin : caUnknown; break; - case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break; - case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break; - case 0x0600: Action = caDblClick; break; - } - - if (Action == caUnknown) - { - LOGWARNING("Received an unknown click action combination: Mode = %d, Button = %d, Slot = %d, HeldItem = %s. Ignoring packet.", - Mode, Button, SlotNum, ItemToFullString(HeldItem).c_str() - ); - ASSERT(!"Unknown click action"); - return PARSE_OK; - } - - m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem); - return PARSE_OK; -} - - - - - diff --git a/src/Protocol/Protocol15x.h b/src/Protocol/Protocol15x.h deleted file mode 100644 index 968d5ebcf..000000000 --- a/src/Protocol/Protocol15x.h +++ /dev/null @@ -1,42 +0,0 @@ - -// Protocol15x.h - -/* -Declares the 1.5.x protocol classes: - - cProtocol150 - - release 1.5 and 1.5.1 protocol (#60) - - release 1.5.2 protocol (#61; no relevant changes found) -*/ - - - - - -#pragma once - -#include "Protocol14x.h" - - - - - -class cProtocol150 : - public cProtocol146 -{ - typedef cProtocol146 super; - -public: - cProtocol150(cClientHandle * a_Client); - - virtual void SendWindowOpen (const cWindow & a_Window) override; - virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; - virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override; - virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override; - - virtual int ParseWindowClick(void); -} ; - - - - diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp deleted file mode 100644 index 0d354a030..000000000 --- a/src/Protocol/Protocol16x.cpp +++ /dev/null @@ -1,312 +0,0 @@ - -// Protocol16x.cpp - -/* -Implements the 1.6.x protocol classes: - - cProtocol161 - - release 1.6.1 protocol (#73) - - cProtocol162 - - release 1.6.2 protocol (#74) - - release 1.6.3 protocol (#77) - no relevant changes - - release 1.6.4 protocol (#78) - no relevant changes -(others may be added later in the future for the 1.6 release series) -*/ - -#include "Globals.h" -#include "Protocol16x.h" -#include "../ClientHandle.h" -#include "../Entities/Entity.h" -#include "../Entities/Player.h" -#include "../UI/Window.h" -#include "../CompositeChat.h" - - - - - -#define HANDLE_PACKET_READ(Proc, Type, Var) \ - Type Var; \ - { \ - if (!m_ReceivedData.Proc(Var)) \ - { \ - m_ReceivedData.CheckValid(); \ - return PARSE_INCOMPLETE; \ - } \ - m_ReceivedData.CheckValid(); \ - } - - - - - -enum -{ - PACKET_CHAT = 0x03, - PACKET_UPDATE_HEALTH = 0x08, - PACKET_STEER_VEHICLE = 0x1b, - PACKET_ATTACH_ENTITY = 0x27, - PACKET_ENTITY_PROPERTIES = 0x2c, - PACKET_WINDOW_OPEN = 0x64, - PACKET_TILE_EDITOR_OPEN = 0x85, - PACKET_PLAYER_ABILITIES = 0xca, -} ; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol161: - -cProtocol161::cProtocol161(cClientHandle * a_Client) : - super(a_Client) -{ -} - - - - - -void cProtocol161::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ATTACH_ENTITY); - WriteInt(a_Entity.GetUniqueID()); - WriteInt((a_Vehicle == NULL) ? -1 : a_Vehicle->GetUniqueID()); - WriteBool(false); // TODO: "Should use leash?" -> no - Flush(); -} - - - - - -void cProtocol161::SendChat(const AString & a_Message) -{ - super::SendChat(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); -} - - - - - -void cProtocol161::SendChat(const cCompositeChat & a_Message) -{ - // This protocol version doesn't support composite messages to the full - // Just extract each part's text and use it: - - super::SendChat(Printf("{\"text\":\"%s\"}", EscapeString(a_Message.ExtractText()).c_str())); -} - - - - - -void cProtocol161::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_TILE_EDITOR_OPEN); - WriteByte(0); - WriteInt(a_BlockX); - WriteInt(a_BlockY); - WriteInt(a_BlockZ); - Flush(); -} - - - - - -void cProtocol161::SendGameMode(eGameMode a_GameMode) -{ - super::SendGameMode(a_GameMode); - SendPlayerMaxSpeed(); -} - - - - - -void cProtocol161::SendHealth(void) -{ - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_UPDATE_HEALTH); - cPlayer * Player = m_Client->GetPlayer(); - WriteFloat((float)Player->GetHealth()); - WriteShort((short)Player->GetFoodLevel()); - WriteFloat((float)Player->GetFoodSaturationLevel()); - Flush(); -} - - - - - -void cProtocol161::SendPlayerMaxSpeed(void) -{ - cCSLock Lock(m_CSPacket); - cPlayer * Player = m_Client->GetPlayer(); - WriteByte(PACKET_ENTITY_PROPERTIES); - WriteInt(Player->GetUniqueID()); - WriteInt(1); - WriteString("generic.movementSpeed"); - WriteDouble(0.1 * Player->GetMaxSpeed()); - Flush(); -} - - - - - -void cProtocol161::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) -{ - // Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast - super::SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks); - SendPlayerMaxSpeed(); -} - - - - - -void cProtocol161::SendWindowOpen(const cWindow & a_Window) -{ - if (a_Window.GetWindowType() < 0) - { - // Do not send for inventory windows - return; - } - cCSLock Lock(m_CSPacket); - WriteByte (PACKET_WINDOW_OPEN); - WriteChar (a_Window.GetWindowID()); - WriteByte ((Byte)a_Window.GetWindowType()); - WriteString(a_Window.GetWindowTitle()); - WriteByte ((Byte)a_Window.GetNumNonInventorySlots()); - WriteByte (1); // Use title - if (a_Window.GetWindowType() == cWindow::wtAnimalChest) - { - WriteInt(0); // TODO: The animal's EntityID - } - Flush(); -} - - - - - -int cProtocol161::ParseEntityAction(void) -{ - HANDLE_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_PACKET_READ(ReadChar, char, ActionID); - HANDLE_PACKET_READ(ReadBEInt, int, UnknownHorseVal); - - switch (ActionID) - { - case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch - case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch - case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed - case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting - case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting - } - - return PARSE_OK; -} - - - - - -int cProtocol161::ParseLogin(void) -{ - // The login packet is sent by Forge clients only - // Only parse the packet, do no extra processing - // Note that the types and the names have been only guessed and are not verified at all! - HANDLE_PACKET_READ(ReadBEInt, int, Int1); - HANDLE_PACKET_READ(ReadBEUTF16String16, AString, String1); - HANDLE_PACKET_READ(ReadChar, char, Char1); - HANDLE_PACKET_READ(ReadChar, char, Char2); - HANDLE_PACKET_READ(ReadChar, char, Char3); - HANDLE_PACKET_READ(ReadByte, Byte, Byte1); - HANDLE_PACKET_READ(ReadByte, Byte, Byte2); - return PARSE_OK; -} - - - - - -int cProtocol161::ParsePlayerAbilities(void) -{ - HANDLE_PACKET_READ(ReadByte, Byte, Flags); - HANDLE_PACKET_READ(ReadBEFloat, float, FlyingSpeed); - HANDLE_PACKET_READ(ReadBEFloat, float, WalkingSpeed); - // TODO: m_Client->HandlePlayerAbilities(...); - return PARSE_OK; -} - - - - - -int cProtocol161::ParseSteerVehicle(void) -{ - HANDLE_PACKET_READ(ReadBEFloat, float, Sideways); - HANDLE_PACKET_READ(ReadBEFloat, float, Forward); - HANDLE_PACKET_READ(ReadBool, bool, Jump); - HANDLE_PACKET_READ(ReadBool, bool, Unmount); - if (Unmount) - { - m_Client->HandleUnmount(); - } - else - { - m_Client->HandleSteerVehicle(Forward, Sideways); - } - return PARSE_OK; -} - - - - - -int cProtocol161::ParsePacket(unsigned char a_PacketType) -{ - switch (a_PacketType) - { - case PACKET_STEER_VEHICLE: return ParseSteerVehicle(); - default: return super::ParsePacket(a_PacketType); - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cProtocol162: - -cProtocol162::cProtocol162(cClientHandle * a_Client) : - super(a_Client) -{ -} - - - - - -void cProtocol162::SendPlayerMaxSpeed(void) -{ - cCSLock Lock(m_CSPacket); - cPlayer * Player = m_Client->GetPlayer(); - WriteByte(PACKET_ENTITY_PROPERTIES); - WriteInt(Player->GetUniqueID()); - WriteInt(1); - WriteString("generic.movementSpeed"); - WriteDouble(0.1 * Player->GetMaxSpeed()); - WriteShort(0); - Flush(); -} - - - - diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h deleted file mode 100644 index add761d1e..000000000 --- a/src/Protocol/Protocol16x.h +++ /dev/null @@ -1,78 +0,0 @@ - -// Protocol16x.h - -/* -Declares the 1.6.x protocol classes: - - cProtocol161 - - release 1.6.1 protocol (#73) - - cProtocol162 - - release 1.6.2 protocol (#74) - - release 1.6.3 protocol (#77) - no relevant changes - - release 1.6.4 protocol (#78) - no relevant changes -(others may be added later in the future for the 1.6 release series) -*/ - - - - - -#pragma once - -#include "Protocol15x.h" - - - - - -class cProtocol161 : - public cProtocol150 -{ - typedef cProtocol150 super; - -public: - cProtocol161(cClientHandle * a_Client); - -protected: - - // cProtocol150 overrides: - virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendChat (const cCompositeChat & a_Message) override; - virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendPlayerMaxSpeed(void) override; - virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override; - virtual void SendWindowOpen (const cWindow & a_Window) override; - - virtual int ParseEntityAction (void) override; - virtual int ParseLogin (void) override; - virtual int ParsePlayerAbilities(void) override; - - // New packets: - virtual int ParseSteerVehicle(void); - - // Enable new packets' handling - virtual int ParsePacket(unsigned char a_PacketType) override; -} ; - - - - - -class cProtocol162 : - public cProtocol161 -{ - typedef cProtocol161 super; - -public: - cProtocol162(cClientHandle * a_Client); - -protected: - // cProtocol161 overrides: - virtual void SendPlayerMaxSpeed(void) override; -} ; - - - - diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index ac58ef28b..e4c33908a 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2217,20 +2217,6 @@ void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) -void cProtocol172::WritePacket(cByteBuffer & a_Packet) -{ - cCSLock Lock(m_CSPacket); - AString Pkt; - a_Packet.ReadAll(Pkt); - WriteVarInt((UInt32)Pkt.size()); - SendData(Pkt.data(), Pkt.size()); - Flush(); -} - - - - - void cProtocol172::SendData(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 8f537f5d7..0bc86a72a 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -296,9 +296,6 @@ protected: void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); - /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */ - void WritePacket(cByteBuffer & a_Packet); - /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index a2dbb7a1f..c983f6671 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2507,20 +2507,6 @@ void cProtocol180::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) -void cProtocol180::WritePacket(cByteBuffer & a_Packet) -{ - cCSLock Lock(m_CSPacket); - AString Pkt; - a_Packet.ReadAll(Pkt); - WriteVarInt((UInt32)Pkt.size()); - SendData(Pkt.data(), Pkt.size()); - Flush(); -} - - - - - void cProtocol180::SendData(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 554edecc8..acc167a6d 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -313,9 +313,6 @@ protected: void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); - /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */ - void WritePacket(cByteBuffer & a_Packet); - /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index fe53aede1..bfa5334d5 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -7,11 +7,6 @@ #include "Globals.h" #include "ProtocolRecognizer.h" -#include "Protocol125.h" -#include "Protocol132.h" -#include "Protocol14x.h" -#include "Protocol15x.h" -#include "Protocol16x.h" #include "Protocol17x.h" #include "Protocol18x.h" #include "../ClientHandle.h" @@ -50,17 +45,6 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) { switch (a_ProtocolVersion) { - case PROTO_VERSION_1_2_5: return "1.2.5"; - case PROTO_VERSION_1_3_2: return "1.3.2"; - // case PROTO_VERSION_1_4_2: return "1.4.2"; - case PROTO_VERSION_1_4_4: return "1.4.4"; - case PROTO_VERSION_1_4_6: return "1.4.6"; - case PROTO_VERSION_1_5_0: return "1.5"; - case PROTO_VERSION_1_5_2: return "1.5.2"; - case PROTO_VERSION_1_6_1: return "1.6.1"; - case PROTO_VERSION_1_6_2: return "1.6.2"; - case PROTO_VERSION_1_6_3: return "1.6.3"; - case PROTO_VERSION_1_6_4: return "1.6.4"; case PROTO_VERSION_1_7_2: return "1.7.2"; case PROTO_VERSION_1_7_6: return "1.7.6"; case PROTO_VERSION_1_8_0: return "1.8"; @@ -206,16 +190,8 @@ void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity) void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) { - if (m_Protocol != NULL) - { - m_Protocol->SendDisconnect(a_Reason); - } - else - { - // This is used when the client sends a server-ping, respond with the default packet: - WriteByte (0xff); // PACKET_DISCONNECT - WriteString(a_Reason); - } + ASSERT(m_Protocol != NULL); + m_Protocol->SendDisconnect(a_Reason); } @@ -873,51 +849,8 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) { // NOTE: If a new protocol is added or an old one is removed, adjust MCS_CLIENT_VERSIONS and // MCS_PROTOCOL_VERSIONS macros in the header file, as well as PROTO_VERSION_LATEST macro - - // The first packet should be a Handshake, 0x02: - unsigned char PacketType; - if (!m_Buffer.ReadByte(PacketType)) - { - return false; - } - switch (PacketType) - { - case 0x02: return TryRecognizeLengthlessProtocol(); // Handshake, continue recognizing - case 0xfe: - { - // This may be either a packet length or the length-less Ping packet - Byte NextByte; - if (!m_Buffer.ReadByte(NextByte)) - { - // Not enough data for either protocol - // This could actually happen with the 1.2 / 1.3 client, but their support is fading out anyway - return false; - } - if (NextByte != 0x01) - { - // This is definitely NOT a length-less Ping packet, handle as lengthed protocol: - break; - } - if (!m_Buffer.ReadByte(NextByte)) - { - // There is no more data. Although this *could* mean TCP fragmentation, it is highly unlikely - // and rather this is a 1.4 client sending a regular Ping packet (without the following Plugin message) - SendLengthlessServerPing(); - return false; - } - if (NextByte == 0xfa) - { - // Definitely a length-less Ping followed by a Plugin message - SendLengthlessServerPing(); - return false; - } - // Definitely a lengthed Initial handshake, handle below: - break; - } - } // switch (PacketType) - // This must be a lengthed protocol, try if it has the entire initial handshake packet: - m_Buffer.ResetRead(); + // Lengthed protocol, try if it has the entire initial handshake packet: UInt32 PacketLen; UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace(); if (!m_Buffer.ReadVarInt(PacketLen)) @@ -938,61 +871,6 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) -bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void) -{ - // The comm started with 0x02, which is a Handshake packet in the length-less protocol family - // 1.3.2 starts with 0x02 0x39 - // 1.2.5 starts with 0x02 and name is expected to less than 0x3900 long :) - char ch; - if (!m_Buffer.ReadChar(ch)) - { - return false; - } - switch (ch) - { - case PROTO_VERSION_1_3_2: - { - m_Protocol = new cProtocol132(m_Client); - return true; - } - case PROTO_VERSION_1_4_2: - case PROTO_VERSION_1_4_4: - { - m_Protocol = new cProtocol142(m_Client); - return true; - } - case PROTO_VERSION_1_4_6: - { - m_Protocol = new cProtocol146(m_Client); - return true; - } - case PROTO_VERSION_1_5_0: - case PROTO_VERSION_1_5_2: - { - m_Protocol = new cProtocol150(m_Client); - return true; - } - case PROTO_VERSION_1_6_1: - { - m_Protocol = new cProtocol161(m_Client); - return true; - } - case PROTO_VERSION_1_6_2: - case PROTO_VERSION_1_6_3: - case PROTO_VERSION_1_6_4: - { - m_Protocol = new cProtocol162(m_Client); - return true; - } - } - m_Protocol = new cProtocol125(m_Client); - return true; -} - - - - - bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining) { UInt32 PacketType; @@ -1090,80 +968,3 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema - -void cProtocolRecognizer::SendLengthlessServerPing(void) -{ - AString Reply; - cServer * Server = cRoot::Get()->GetServer(); - - AString ServerDescription = Server->GetDescription(); - int NumPlayers = Server->GetNumPlayers(); - int MaxPlayers = Server->GetMaxPlayers(); - AString Favicon = Server->GetFaviconData(); - cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); - - switch (cRoot::Get()->GetPrimaryServerVersion()) - { - case PROTO_VERSION_1_2_5: - case PROTO_VERSION_1_3_2: - { - // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 - Printf(Reply, "%s%s%i%s%i", - ServerDescription.c_str(), - cChatColor::Delimiter, - NumPlayers, - cChatColor::Delimiter, - MaxPlayers - ); - break; - } - - case PROTO_VERSION_1_4_2: - case PROTO_VERSION_1_4_4: - case PROTO_VERSION_1_4_6: - case PROTO_VERSION_1_5_0: - case PROTO_VERSION_1_5_2: - case PROTO_VERSION_1_6_1: - case PROTO_VERSION_1_6_2: - case PROTO_VERSION_1_6_3: - case PROTO_VERSION_1_6_4: - { - // The server list ping now has 1 more byte of "magic". Mojang just loves to complicate stuff. - // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3101#Server_List_Ping_.280xFE.29 - // _X 2012_10_31: I know that this needn't eat the byte, since it still may be in transit. - // Who cares? We're disconnecting anyway. - m_Buffer.ResetRead(); - if (m_Buffer.CanReadBytes(2)) - { - Byte val; - m_Buffer.ReadByte(val); // Packet type - Serverlist ping - m_Buffer.ReadByte(val); // 0x01 magic value - ASSERT(val == 0x01); - } - - AString ProtocolVersionNum; - Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion()); - AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion())); - - // Cannot use Printf() because of in-string NUL bytes. - Reply = cChatColor::Delimiter; - Reply.append("1"); - Reply.push_back(0); - Reply.append(ProtocolVersionNum); - Reply.push_back(0); - Reply.append(ProtocolVersionTxt); - Reply.push_back(0); - Reply.append(ServerDescription); - Reply.push_back(0); - Reply.append(Printf("%d", NumPlayers)); - Reply.push_back(0); - Reply.append(Printf("%d", MaxPlayers)); - break; - } - } // switch (m_PrimaryServerVersion) - m_Client->Kick(Reply); -} - - - - diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index e4419f6ae..96a7e17d2 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -18,8 +18,8 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10, 1.8" -#define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5" +#define MCS_CLIENT_VERSIONS "1.7.x, 1.8" +#define MCS_PROTOCOL_VERSIONS "4, 5, 47" @@ -33,22 +33,6 @@ class cProtocolRecognizer : public: enum { - PROTO_VERSION_1_2_5 = 29, - PROTO_VERSION_1_3_2 = 39, - PROTO_VERSION_1_4_2 = 47, - PROTO_VERSION_1_4_4 = 49, - PROTO_VERSION_1_4_6 = 51, - PROTO_VERSION_1_5_0 = 60, - PROTO_VERSION_1_5_2 = 61, - PROTO_VERSION_1_6_1 = 73, - PROTO_VERSION_1_6_2 = 74, - PROTO_VERSION_1_6_3 = 77, - PROTO_VERSION_1_6_4 = 78, - - PROTO_VERSION_NEXT, - PROTO_VERSION_LATEST = PROTO_VERSION_NEXT - 1, ///< Automatically assigned to the last protocol version, this serves as the default for PrimaryServerVersion - - // These will be kept "under" the next / latest, because the next and latest are only needed for previous protocols PROTO_VERSION_1_7_2 = 4, PROTO_VERSION_1_7_6 = 5, PROTO_VERSION_1_8_0 = 47, @@ -150,23 +134,11 @@ protected: /// Tries to recognize protocol based on m_Buffer contents; returns true if recognized bool TryRecognizeProtocol(void); - /** Tries to recognize a protocol in the length-less family, based on m_Buffer; returns true if recognized. - Handles protocols before release 1.7, that didn't include packet lengths, and started with a 0x02 handshake packet - Note that length-less server ping is handled directly in TryRecognizeProtocol(), this function is called only - when the 0x02 Handshake packet has been received - */ - bool TryRecognizeLengthlessProtocol(void); - /** Tries to recognize a protocol in the leghted family (1.7+), based on m_Buffer; returns true if recognized. The packet length and type have already been read, type is 0 The number of bytes remaining in the packet is passed as a_PacketLengthRemaining **/ bool TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining); - - /** Called when the recognizer gets a length-less protocol's server ping packet - Responds with server stats and destroys the client. - */ - void SendLengthlessServerPing(void); } ; diff --git a/src/Root.cpp b/src/Root.cpp index 966a9b4ba..aa3d43cba 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -42,7 +42,6 @@ cRoot* cRoot::s_Root = NULL; cRoot::cRoot(void) : - m_PrimaryServerVersion(cProtocolRecognizer::PROTO_VERSION_LATEST), m_pDefaultWorld(NULL), m_InputThread(NULL), m_Server(NULL), @@ -142,17 +141,6 @@ void cRoot::Start(void) IniFile.AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help"); } - m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); - if (m_PrimaryServerVersion == 0) - { - m_PrimaryServerVersion = cProtocolRecognizer::PROTO_VERSION_LATEST; - } - else - { - // Make a note in the log that the primary server version is explicitly set in the ini file - LOGINFO("Primary server version set explicitly to %d.", m_PrimaryServerVersion); - } - LOG("Starting server..."); m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init if (!m_Server->InitServer(IniFile)) diff --git a/src/Root.h b/src/Root.h index 9bc975889..9a482556c 100644 --- a/src/Root.h +++ b/src/Root.h @@ -73,9 +73,6 @@ public: /// Writes chunkstats, for each world and totals, to the output callback void LogChunkStats(cCommandOutputCallback & a_Output); - int GetPrimaryServerVersion(void) const { return m_PrimaryServerVersion; } // tolua_export - void SetPrimaryServerVersion(int a_Version) { m_PrimaryServerVersion = a_Version; } // tolua_export - cMonsterConfig * GetMonsterConfig(void) { return m_MonsterConfig; } cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export @@ -169,9 +166,6 @@ private: typedef std::map WorldMap; typedef std::vector cCommandQueue; - - /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported. - int m_PrimaryServerVersion; cWorld * m_pDefaultWorld; WorldMap m_WorldsByName; -- cgit v1.2.3 From 4f8818748e8b32bc58e251bbd359216554c3e6c6 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 27 Sep 2014 14:46:50 +0100 Subject: Add data accessor. --- src/Chunk.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Chunk.h b/src/Chunk.h index b525fbb82..bc66b6528 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -421,6 +421,7 @@ public: cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; } cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return m_RedstoneSimulatorData; } + void SetRedstoneSimulatorData(cRedstoneSimulatorChunkData * a_Data) { m_RedstoneSimulatorData = a_Data; } bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; } void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; } -- cgit v1.2.3 From 94a0d04d58110d3a54669c0b7bbb7f0a618a60bd Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 27 Sep 2014 14:49:03 +0100 Subject: Set chunk data --- src/Simulator/IncrementalRedstoneSimulator.inc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index 6fda9824c..ba67d4014 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -554,6 +554,11 @@ template class Get void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) { m_RedstoneSimulatorChunkData = (cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData(); + if (m_RedstoneSimulatorChunkData == NULL) + { + m_RedstoneSimulatorChunkData = new cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData(); + a_Chunk->SetRedstoneChunkData(m_RedstoneSimulatorChunkData); + } if (m_RedstoneSimulatorChunkData->m_ChunkData.empty() && ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData.empty()) { return; -- cgit v1.2.3 From 20101fab996a8c84225508502cfbe8491a7bb0ac Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 27 Sep 2014 15:04:08 +0100 Subject: Correct method name. --- src/Simulator/IncrementalRedstoneSimulator.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index ba67d4014..c5cfbe3ed 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -557,7 +557,7 @@ void cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData(); - a_Chunk->SetRedstoneChunkData(m_RedstoneSimulatorChunkData); + a_Chunk->SetRedstoneData(m_RedstoneSimulatorChunkData); } if (m_RedstoneSimulatorChunkData->m_ChunkData.empty() && ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData.empty()) { -- cgit v1.2.3 From 88a07bd18461e04ca57b049ac6dff7deada5d298 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 27 Sep 2014 15:19:32 +0100 Subject: Update IncrementalRedstoneSimulator.inc --- src/Simulator/IncrementalRedstoneSimulator.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index c5cfbe3ed..299656b85 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -557,7 +557,7 @@ void cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData(); - a_Chunk->SetRedstoneData(m_RedstoneSimulatorChunkData); + a_Chunk->SetRedstoneSimulatorData(m_RedstoneSimulatorChunkData); } if (m_RedstoneSimulatorChunkData->m_ChunkData.empty() && ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_QueuedChunkData.empty()) { -- cgit v1.2.3 From cc73b70211ecab462edd373ebfd9f917250321c7 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 27 Sep 2014 15:24:01 +0100 Subject: Update IncrementalRedstoneSimulator.inc --- src/Simulator/IncrementalRedstoneSimulator.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index 299656b85..adaa47967 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -77,7 +77,7 @@ private: }; class cIncrementalRedstoneSimulatorChunkData : - cRedstoneSimulatorChunkData + public cRedstoneSimulatorChunkData { public: /// Per-chunk data for the simulator, specified individual chunks to simulate -- cgit v1.2.3 From 7ce09a9113d693b85fdda13b3c04a8b8eb900153 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 27 Sep 2014 19:19:28 +0100 Subject: Suggestions --- src/BlockEntities/BlockEntityWithItems.h | 12 +++--- src/BlockEntities/EnderChestEntity.cpp | 3 +- src/BlockEntities/EnderChestEntity.h | 2 +- src/Entities/Minecart.cpp | 4 +- src/Entities/Minecart.h | 3 +- src/UI/WindowOwner.h | 68 ++++++++++++++++++++++++++------ 6 files changed, 69 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index ca6758e7a..f26ef07dd 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -20,12 +20,9 @@ // tolua_begin class cBlockEntityWithItems : - public cBlockEntity - // tolua_end - // tolua doesn't seem to support multiple inheritance? - , public cItemGrid::cListener - , public cWindowOwner - // tolua_begin + public cBlockEntity, + public cItemGrid::cListener, + public cBlockEntityWindowOwner { typedef cBlockEntity super; @@ -39,7 +36,8 @@ public: cWorld * a_World // Optional world to assign to the entity ) : super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World), - m_Contents(a_ItemGridWidth, a_ItemGridHeight) + m_Contents(a_ItemGridWidth, a_ItemGridHeight), + cBlockEntityWindowOwner(this) { m_Contents.AddListener(*this); } diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp index b870f9e50..0654d97dd 100644 --- a/src/BlockEntities/EnderChestEntity.cpp +++ b/src/BlockEntities/EnderChestEntity.cpp @@ -11,7 +11,8 @@ cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : - super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World) + super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World), + cBlockEntityWindowOwner(this) { } diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index ccfb2690b..311af8d76 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -11,7 +11,7 @@ // tolua_begin class cEnderChestEntity : public cBlockEntity, - public cWindowOwner + public cBlockEntityWindowOwner { typedef cBlockEntity super; diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 42ac57a07..c5e1c07d5 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -7,7 +7,6 @@ #include "Globals.h" #include "Minecart.h" -#include "../World.h" #include "../ClientHandle.h" #include "../Chunk.h" #include "Player.h" @@ -1107,7 +1106,8 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player) cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) : super(mpChest, a_X, a_Y, a_Z), - m_Contents(ContentsWidth, ContentsHeight) + m_Contents(ContentsWidth, ContentsHeight), + cEntityWindowOwner(this) { m_Contents.AddListener(*this); } diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index f77a171ba..6b6ad36b5 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -10,6 +10,7 @@ #pragma once #include "Entity.h" +#include "World.h" #include "../UI/WindowOwner.h" @@ -111,7 +112,7 @@ protected: class cMinecartWithChest : public cMinecart, public cItemGrid::cListener, - public cWindowOwner + public cEntityWindowOwner { typedef cMinecart super; diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h index a8be3e6cb..6845a161b 100644 --- a/src/UI/WindowOwner.h +++ b/src/UI/WindowOwner.h @@ -1,4 +1,3 @@ - #pragma once #include "../BlockEntities/BlockEntity.h" @@ -16,12 +15,6 @@ for entities / players in motion to close their windows when they get too far aw -// class cWindow; - - - - - /** Base class for the window owning */ @@ -32,16 +25,16 @@ public: m_Window(NULL) { } - + virtual ~cWindowOwner() { } - + void CloseWindow(void) { m_Window = NULL; } - + void OpenWindow(cWindow * a_Window) { m_Window = a_Window; @@ -52,7 +45,10 @@ public: { return m_Window; } - + + /// Returns the block position at which the element owning the window is + virtual Vector3i GetBlockPos(void) = 0; + private: cWindow * m_Window; }; @@ -60,3 +56,53 @@ private: + +/** +Window owner that is associated with a block entity (chest, furnace, ...) +*/ +class cBlockEntityWindowOwner : + public cWindowOwner +{ +public: + cBlockEntityWindowOwner(cBlockEntity * a_BlockEntity) : + m_BlockEntity(a_BlockEntity) + { + } + + virtual Vector3i GetBlockPos(void) override + { + return Vector3i(m_BlockEntity->GetPosX(), m_BlockEntity->GetPosY(), m_BlockEntity->GetPosZ()); + } + +private: + cBlockEntity * m_BlockEntity; +}; + + + + + +/** +Window owner that is associated with an entity (chest minecart) +*/ +class cEntityWindowOwner : + public cWindowOwner +{ +public: + cEntityWindowOwner(cEntity * a_Entity) : + m_Entity(a_Entity) + { + } + + virtual Vector3i GetBlockPos(void) override + { + return m_Entity->GetPosition().Floor(); + } + +private: + cEntity * m_Entity; +}; + + + + -- cgit v1.2.3 From fc22ba0ce89b12b13bca00f5005f96528d1c91ae Mon Sep 17 00:00:00 2001 From: Masy98 Date: Sat, 27 Sep 2014 21:07:52 +0200 Subject: Added barriers correctly --- src/ChunkMap.cpp | 1 + src/ClientHandle.cpp | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 38a7d9bd4..299fe0eca 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1888,6 +1888,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ case E_BLOCK_OBSIDIAN: case E_BLOCK_BEACON: case E_BLOCK_BEDROCK: + case E_BLOCK_BARRIER: case E_BLOCK_WATER: case E_BLOCK_LAVA: { diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 878d309c9..52ea59884 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1153,6 +1153,11 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo Kick("You can't break a bedrock!"); return; } + if (!m_Player->IsGameModeCreative() && (a_OldBlock == E_BLOCK_BARRIER)) + { + Kick("You can't break a barrier!"); + return; + } cWorld * World = m_Player->GetWorld(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); -- cgit v1.2.3 From d1a72eb6de22d6b8fd4ba126e796baca68c0ae2b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 27 Sep 2014 21:33:50 +0200 Subject: Wrapped clang-specific pragma into an #ifdef block. MSVC was complaining about an unknown pragma. --- src/Simulator/Simulator.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index d26702166..29a1132ad 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -8,6 +8,11 @@ #include "Simulator.inc" -#pragma clang diagnostic ignored "-Wweak-template-vtables" +#ifdef __clang__ + #pragma clang diagnostic ignored "-Wweak-template-vtables" +#endif // __clang__ + template class cSimulator; + + -- cgit v1.2.3 From e7de548c89e8ece5b0d66f597a9690d8ada5b2ad Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 27 Sep 2014 21:37:36 +0200 Subject: Fixed minor style issues. --- src/BlockInfo.cpp | 2 +- src/Blocks/ChunkInterface.cpp | 2 +- src/Mobs/Monster.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index fb9b746b3..14e814084 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -734,7 +734,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; - a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // I hope it is named slime, it's definetly a new sound type though... + a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // TODO: Check that this is the correct name a_Info[E_BLOCK_BARRIER ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal"; a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone"; diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index e22a1410e..817640e98 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -4,7 +4,7 @@ #include "ChunkInterface.h" #include "ChunkMap.h" #include "BlockHandler.h" -#include "WorldInterface.h" +#include "WorldInterface.h" diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index ba746ebc8..a1f9c4a5b 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -25,7 +25,7 @@ class cMonster : typedef cPawn super; public: - //Depreciated + // Deprecated typedef eMonsterType eType; enum eFamily -- cgit v1.2.3 From 79110b29dbdfafae13ae4448b1672b129ebf7128 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Sat, 27 Sep 2014 21:49:03 +0200 Subject: Combined conditions --- src/ClientHandle.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 52ea59884..3bd48eb3d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1148,15 +1148,18 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo FinishDigAnimation(); - if (!m_Player->IsGameModeCreative() && (a_OldBlock == E_BLOCK_BEDROCK)) - { - Kick("You can't break a bedrock!"); - return; - } - if (!m_Player->IsGameModeCreative() && (a_OldBlock == E_BLOCK_BARRIER)) + if (!m_Player->IsGameModeCreative()) { - Kick("You can't break a barrier!"); - return; + if (a_OldBlock == E_BLOCK_BEDROCK) + { + Kick("You can't break a bedrock!"); + return; + } + if (a_OldBlock == E_BLOCK_BARRIER) + { + Kick("You can't break a barrier!"); + return; + } } cWorld * World = m_Player->GetWorld(); -- cgit v1.2.3 From 113b54aefda025f3cb47d5285e12104e8681506e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 27 Sep 2014 22:01:47 +0200 Subject: BioGen: TwoLevel is now fully settable in INI. --- src/Generating/BioGen.cpp | 60 +++++++++++++++++------------------------------ src/Generating/BioGen.h | 15 +++++++----- 2 files changed, 31 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 3ee0bd4c5..8924a7999 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -737,8 +737,6 @@ void cBioGenMultiStepMap::FreezeWaterBiomes(cChunkDef::BiomeMap & a_BiomeMap, co cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) : m_VoronoiLarge(a_Seed + 1000), m_VoronoiSmall(a_Seed + 2000), - m_DistortX(a_Seed + 3000), - m_DistortZ(a_Seed + 4000), m_Noise1(a_Seed + 5001), m_Noise2(a_Seed + 5002), m_Noise3(a_Seed + 5003), @@ -762,19 +760,17 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; for (int x = 0; x <= 4; x++) for (int z = 0; z <= 4; z++) { - int BlockX = BaseX + x * 4; - int BlockZ = BaseZ + z * 4; - float BlockXF = (float)(16 * BlockX) / 128; - float BlockZF = (float)(16 * BlockZ) / 128; - double NoiseX = m_Noise1.CubicNoise2D(BlockXF / 16, BlockZF / 16); - NoiseX += 0.5 * m_Noise2.CubicNoise2D(BlockXF / 8, BlockZF / 8); - NoiseX += 0.08 * m_Noise3.CubicNoise2D(BlockXF, BlockZF); - double NoiseZ = m_Noise4.CubicNoise2D(BlockXF / 16, BlockZF / 16); - NoiseZ += 0.5 * m_Noise5.CubicNoise2D(BlockXF / 8, BlockZF / 8); - NoiseZ += 0.08 * m_Noise6.CubicNoise2D(BlockXF, BlockZF); + float BlockX = BaseX + x * 4; + float BlockZ = BaseZ + z * 4; + double NoiseX = m_AmpX1 * m_Noise1.CubicNoise2D(BlockX * m_FreqX1, BlockZ * m_FreqX1); + NoiseX += m_AmpX2 * m_Noise2.CubicNoise2D(BlockX * m_FreqX2, BlockZ * m_FreqX2); + NoiseX += m_AmpX3 * m_Noise3.CubicNoise2D(BlockX * m_FreqX3, BlockZ * m_FreqX3); + double NoiseZ = m_AmpZ1 * m_Noise4.CubicNoise2D(BlockX * m_FreqZ1, BlockZ * m_FreqZ1); + NoiseZ += m_AmpZ2 * m_Noise5.CubicNoise2D(BlockX * m_FreqZ2, BlockZ * m_FreqZ2); + NoiseZ += m_AmpZ3 * m_Noise6.CubicNoise2D(BlockX * m_FreqZ3, BlockZ * m_FreqZ3); - DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX); - DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ); + DistortX[4 * x][4 * z] = (int)(BlockX + NoiseX); + DistortZ[4 * x][4 * z] = (int)(BlockZ + NoiseZ); } LinearUpscale2DArrayInPlace(&DistortX[0][0]); @@ -915,30 +911,18 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile) { m_VoronoiLarge.SetCellSize(a_IniFile.GetValueSetI("Generator", "TwoLevelLargeCellSize", 1024)); m_VoronoiSmall.SetCellSize(a_IniFile.GetValueSetI("Generator", "TwoLevelSmallCellSize", 128)); - m_DistortX.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Freq", 0.01), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Amp", 16) - ); - m_DistortX.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Freq", 0.005), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Amp", 8) - ); - m_DistortX.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Freq", 0.0025), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Amp", 4) - ); - m_DistortZ.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Freq", 0.01), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Amp", 16) - ); - m_DistortZ.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Freq", 0.005), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Amp", 8) - ); - m_DistortZ.AddOctave( - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Freq", 0.0025), - (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Amp", 4) - ); + m_FreqX1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Freq", 0.01); + m_AmpX1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Amp", 80); + m_FreqX2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Freq", 0.05); + m_AmpX2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Amp", 20); + m_FreqX3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Freq", 0.1), + m_AmpX3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Amp", 8); + m_FreqZ1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Freq", 0.01); + m_AmpZ1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Amp", 80); + m_FreqZ2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Freq", 0.05); + m_AmpZ2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Amp", 20); + m_FreqZ3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Freq", 0.1); + m_AmpZ3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Amp", 8); } diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index 20d199611..22ddfae5c 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -285,12 +285,7 @@ protected: /// The Voronoi map that decides biomes inside individual biome groups cVoronoiMap m_VoronoiSmall; - /// The noise used to distort the input X coord - cPerlinNoise m_DistortX; - - /// The noise used to distort the inupt Z coord - cPerlinNoise m_DistortZ; - + // The noises used for the distortion: cNoise m_Noise1; cNoise m_Noise2; cNoise m_Noise3; @@ -298,6 +293,14 @@ protected: cNoise m_Noise5; cNoise m_Noise6; + // Frequencies and amplitudes for the distortion noises: + float m_FreqX1, m_AmpX1; + float m_FreqX2, m_AmpX2; + float m_FreqX3, m_AmpX3; + float m_FreqZ1, m_AmpZ1; + float m_FreqZ2, m_AmpZ2; + float m_FreqZ3, m_AmpZ3; + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; -- cgit v1.2.3 From 03791b1e632e8494ba5e261f430d8a8d91a599b8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 27 Sep 2014 22:24:49 +0200 Subject: Fixed another redstone crash. --- src/Simulator/IncrementalRedstoneSimulator.inc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index adaa47967..937e6b790 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -408,7 +408,12 @@ void cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData())->m_PoweredBlocks; + cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData * SimulatorChunkData = ((cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulatorChunkData *)a_Chunk->GetRedstoneSimulatorData()); + if (SimulatorChunkData == NULL) + { + return; + } + PoweredBlocksList & PoweredBlocks = SimulatorChunkData->m_PoweredBlocks; for (typename PoweredBlocksList::iterator itr = PoweredBlocks.begin(); itr != PoweredBlocks.end();) { if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) -- cgit v1.2.3 From 1f8ee70d55d0d076583e14329ca09377c41b12e0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 27 Sep 2014 22:13:37 +0100 Subject: Bug fix --- src/ByteBuffer.cpp | 17 ----------------- src/ByteBuffer.h | 1 - src/Protocol/ProtocolRecognizer.cpp | 17 +++++++++++++++-- src/StringUtils.cpp | 20 ++++++++++---------- src/StringUtils.h | 4 ++-- 5 files changed, 27 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 70fdc008c..dc6b32a44 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -627,23 +627,6 @@ bool cByteBuffer::WriteBool(bool a_Value) -bool cByteBuffer::WriteBEUTF16String16(const AString & a_Value) -{ - CHECK_THREAD; - CheckValid(); - PUTBYTES(2); - AString UTF16BE; - UTF8ToRawBEUTF16(a_Value.data(), a_Value.size(), UTF16BE); - WriteBEShort((short)(UTF16BE.size() / 2)); - PUTBYTES(UTF16BE.size()); - WriteBuf(UTF16BE.data(), UTF16BE.size()); - return true; -} - - - - - bool cByteBuffer::WriteVarInt(UInt32 a_Value) { CHECK_THREAD; diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index 74dc378d4..70de419f0 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -88,7 +88,6 @@ public: bool WriteBEFloat (float a_Value); bool WriteBEDouble (double a_Value); bool WriteBool (bool a_Value); - bool WriteBEUTF16String16(const AString & a_Value); // string length as BE short, then string as UTF-16BE bool WriteVarInt (UInt32 a_Value); bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8 bool WriteLEInt (int a_Value); diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index bfa5334d5..93d7cf0aa 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -190,8 +190,21 @@ void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity) void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) { - ASSERT(m_Protocol != NULL); - m_Protocol->SendDisconnect(a_Reason); + if (m_Protocol != NULL) + { + m_Protocol->SendDisconnect(a_Reason); + } + else + { + // This is used when the client sends a server-ping, respond with the default packet: + static const int Packet = 0xff; // PACKET_DISCONNECT + SendData((const char *)&Packet, 1); // WriteByte() + + AString & UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length()); + static const short Size = htons((short)(UTF16.size() / 2)); + SendData((const char *)&Size, 2); // WriteShort() + SendData(UTF16.data(), UTF16.size()); // WriteString() + } } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 73147eebc..21962f832 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -441,10 +441,10 @@ static bool isLegalUTF8(const unsigned char * source, int length) -AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16) +AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length) { - a_UTF16.clear(); - a_UTF16.reserve(a_UTF8Length * 3); + AString UTF16; + UTF16.reserve(a_UTF8Length * 3); const unsigned char * source = (const unsigned char*)a_UTF8; const unsigned char * sourceEnd = source + a_UTF8Length; @@ -458,12 +458,12 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { - return a_UTF16; + return UTF16; } // Do this check whether lenient or strict if (!isLegalUTF8(source, extraBytesToRead + 1)) { - return a_UTF16; + return UTF16; } // The cases all fall through. See "Note A" below. @@ -487,13 +487,13 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a ch = ' '; } unsigned short v = htons((unsigned short)ch); - a_UTF16.append((const char *)&v, 2); + UTF16.append((const char *)&v, 2); } else if (ch > UNI_MAX_UTF16) { // Invalid value, replace with a space unsigned short v = htons(' '); - a_UTF16.append((const char *)&v, 2); + UTF16.append((const char *)&v, 2); } else { @@ -501,11 +501,11 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a ch -= halfBase; unsigned short v1 = htons((ch >> halfShift) + UNI_SUR_HIGH_START); unsigned short v2 = htons((ch & halfMask) + UNI_SUR_LOW_START); - a_UTF16.append((const char *)&v1, 2); - a_UTF16.append((const char *)&v2, 2); + UTF16.append((const char *)&v1, 2); + UTF16.append((const char *)&v2, 2); } } - return a_UTF16; + return UTF16; } /* diff --git a/src/StringUtils.h b/src/StringUtils.h index a76894d05..159e8ecac 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -66,8 +66,8 @@ extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AS /// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8 extern AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8); -/// Converts a UTF-8 string into a UTF-16 BE string, packing that back into AString; return a ref to a_UTF16 -extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16); +/// Converts a UTF-8 string into a UTF-16 BE string; returns a ref to a_UTF16 +extern AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length); /// Creates a nicely formatted HEX dump of the given memory block. Max a_BytesPerLine is 120 extern AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, size_t a_BytesPerLine); -- cgit v1.2.3 From 04ee8c43dd17eb98d1e3d66ff691898e9f269b95 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 27 Sep 2014 23:22:26 +0200 Subject: 1.8: Fixed plugin messages. --- src/Protocol/Protocol18x.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index a2dbb7a1f..4ec447401 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -989,7 +989,6 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); - Pkt.WriteVarInt((UInt32)a_Message.size()); Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -2316,9 +2315,11 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); AString Data; - a_ByteBuffer.ReadString(Data, DataLen); + if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) + { + return; + } m_Client->HandlePluginMessage(Channel, Data); } -- cgit v1.2.3 From 2fb3eb3532c2c40e21def269cb9d5ca6eb11ef6d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 28 Sep 2014 02:17:32 +0200 Subject: cRankManager: Added GetAllPlayers() and GetPlayerName() --- src/Bindings/ManualBindings_RankManager.cpp | 61 ++++++++++++++++++++++ src/Entities/Player.cpp | 5 ++ src/RankManager.cpp | 81 +++++++++++++++++++++++++++++ src/RankManager.h | 10 ++++ 4 files changed, 157 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 2e93ad264..b43cd9ef2 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -183,6 +183,33 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) +/** Binds cRankManager::GetAllPlayers */ +static int tolua_cRankManager_GetAllPlayers(lua_State * L) +{ + // Function signature: + // cRankManager:GetAllPlayers() -> arraytable of Player UUID's + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the player uuid's: + AStringVector Players = cRoot::Get()->GetRankManager().GetAllPlayers(); + + // Push the results: + S.Push(Players); + return 1; +} + + + + + /** Binds cRankManager::GetAllRanks */ static int tolua_cRankManager_GetAllRanks(lua_State * L) { @@ -400,6 +427,38 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) +/** Binds cRankManager::GetPlayerName */ +static int tolua_cRankManager_GetPlayerName(lua_State * L) +{ + // Function signature: + // cRankManager:GetPlayerName(PlayerUUID) -> string + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the player name: + AString PlayerName = cRoot::Get()->GetRankManager().GetPlayerName(PlayerUUID); + + // Push the result: + S.Push(PlayerName); + return 1; +} + + + + + /** Binds cRankManager::GetRankGroups */ static int tolua_cRankManager_GetRankGroups(lua_State * L) { @@ -974,6 +1033,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "AddRank", tolua_cRankManager_AddRank); tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); + tolua_function(tolua_S, "GetAllPlayers", tolua_cRankManager_GetAllPlayers); tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); tolua_function(tolua_S, "GetDefaultRank", tolua_cRankManager_GetDefaultRank); tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); @@ -981,6 +1041,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "GetPlayerMsgVisuals", tolua_cRankManager_GetPlayerMsgVisuals); tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); + tolua_function(tolua_S, "GetPlayerName", tolua_cRankManager_GetPlayerName); tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 66da14c0c..f58a0a016 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2140,6 +2140,11 @@ void cPlayer::LoadRank(void) { m_Rank = RankMgr.GetDefaultRank(); } + else + { + // Update the name: + RankMgr.UpdatePlayerName(m_UUID, m_PlayerName); + } m_Permissions = RankMgr.GetPlayerPermissions(m_UUID); RankMgr.GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index e5896f8f3..0f267473a 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -496,6 +496,33 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) +AString cRankManager::GetPlayerName(const AString & a_PlayerUUID) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + // Prepare the DB statement: + SQLite::Statement stmt(m_DB, "SELECT PlayerName FROM PlayerRank WHERE PlayerUUID = ?"); + stmt.bind(1, a_PlayerUUID); + + if (stmt.executeStep()) + { + return stmt.getColumn(0).getText(); + } + } + catch (SQLite::Exception & ex) + { + LOGWARNING("%s: Cannot get player name: %s", __FUNCTION__, ex.what()); + } + return AString(); +} + + + + + AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); @@ -636,6 +663,32 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) +AStringVector cRankManager::GetAllPlayers(void) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, "SELECT PlayerUUID FROM PlayerRank"); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get players from DB: %s", __FUNCTION__, ex.what()); + } + return res; +} + + + + + + AStringVector cRankManager::GetAllRanks(void) { ASSERT(m_IsInitialized); @@ -1764,6 +1817,34 @@ bool cRankManager::SetDefaultRank(const AString & a_RankName) +bool cRankManager::UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET PlayerName = ? WHERE PlayerUUID = ?"); + stmt.bind(1, a_NewPlayerName); + stmt.bind(2, a_PlayerUUID); + if (stmt.exec() > 0) + { + // The player name was changed, returns true + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to update player name from UUID %s: %s", __FUNCTION__, a_PlayerUUID.c_str(), ex.what()); + } + return false; +} + + + + + + bool cRankManager::AreDBTablesEmpty(void) { return ( diff --git a/src/RankManager.h b/src/RankManager.h index f364bba6a..ebdba17a0 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -60,6 +60,10 @@ public: If the player has no rank assigned, returns an empty string (NOT the default rank). */ AString GetPlayerRankName(const AString & a_PlayerUUID); + /** Returns the last name that the specified player has. + If the player isn't in the database, this returns an empty string. */ + AString GetPlayerName(const AString & a_PlayerUUID); + /** Returns the names of Groups that the specified player has assigned to them. */ AStringVector GetPlayerGroups(const AString & a_PlayerUUID); @@ -79,6 +83,9 @@ public: Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankPermissions(const AString & a_RankName); + /** Returns the short uuids of all defined players. */ + AStringVector GetAllPlayers(void); + /** Returns the names of all defined ranks. */ AStringVector GetAllRanks(void); @@ -210,6 +217,9 @@ public: /** Returns the name of the default rank. */ const AString & GetDefaultRank(void) const { return m_DefaultRank; } + + /** Updates the playername that is saved with this uuid. Returns false if a error occurred */ + bool UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName); protected: -- cgit v1.2.3 From 27331da017625c748a104c72d72c8958003e1e90 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 28 Sep 2014 11:17:36 +0200 Subject: Updated api documentation. --- src/RankManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/RankManager.h b/src/RankManager.h index ebdba17a0..b577fad05 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -61,7 +61,7 @@ public: AString GetPlayerRankName(const AString & a_PlayerUUID); /** Returns the last name that the specified player has. - If the player isn't in the database, this returns an empty string. */ + An empty string is returned if the player isn't in the database. */ AString GetPlayerName(const AString & a_PlayerUUID); /** Returns the names of Groups that the specified player has assigned to them. */ -- cgit v1.2.3 From ae36ba5d33b1ce61fab33ffc310da6bba38ca316 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 28 Sep 2014 13:08:00 +0100 Subject: Compilation fix --- src/Protocol/ProtocolRecognizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 93d7cf0aa..ef6802d2b 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -200,7 +200,7 @@ void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) static const int Packet = 0xff; // PACKET_DISCONNECT SendData((const char *)&Packet, 1); // WriteByte() - AString & UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length()); + AString UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length()); static const short Size = htons((short)(UTF16.size() / 2)); SendData((const char *)&Size, 2); // WriteShort() SendData(UTF16.data(), UTF16.size()); // WriteString() -- cgit v1.2.3 From a9243257e583ae22d7a27f6439f6eb973f7e11ce Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 28 Sep 2014 13:11:41 +0100 Subject: Compilation fix --- src/BlockEntities/BlockEntityWithItems.h | 4 ++-- src/Entities/Minecart.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index f26ef07dd..00173cbcb 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -36,8 +36,8 @@ public: cWorld * a_World // Optional world to assign to the entity ) : super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World), - m_Contents(a_ItemGridWidth, a_ItemGridHeight), - cBlockEntityWindowOwner(this) + cBlockEntityWindowOwner(this), + m_Contents(a_ItemGridWidth, a_ItemGridHeight) { m_Contents.AddListener(*this); } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index c5e1c07d5..f45e7bb69 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1106,8 +1106,8 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player) cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) : super(mpChest, a_X, a_Y, a_Z), - m_Contents(ContentsWidth, ContentsHeight), - cEntityWindowOwner(this) + cEntityWindowOwner(this), + m_Contents(ContentsWidth, ContentsHeight) { m_Contents.AddListener(*this); } -- cgit v1.2.3 From 63c53a8e23776cc3011fd0260857bd22274e2c62 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 28 Sep 2014 15:16:11 +0200 Subject: cRankManager: Added ClearPlayerRanks() --- src/Bindings/ManualBindings_RankManager.cpp | 22 ++++++++++++++++++++++ src/RankManager.cpp | 19 +++++++++++++++++++ src/RankManager.h | 4 ++++ 3 files changed, 45 insertions(+) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index b43cd9ef2..cddf1ec2e 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -129,6 +129,27 @@ static int tolua_cRankManager_AddRank(lua_State * L) +/** Binds cRankManager::ClearPlayerRanks */ +static int tolua_cRankManager_ClearPlayerRanks(lua_State * L) +{ + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Remove all players: + cRoot::Get()->GetRankManager().ClearPlayerRanks(); + return 1; +} + + + + + /** Binds cRankManager::GetAllGroups */ static int tolua_cRankManager_GetAllGroups(lua_State * L) { @@ -1031,6 +1052,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "AddGroupToRank", tolua_cRankManager_AddGroupToRank); tolua_function(tolua_S, "AddPermissionToGroup", tolua_cRankManager_AddPermissionToGroup); tolua_function(tolua_S, "AddRank", tolua_cRankManager_AddRank); + tolua_function(tolua_S, "ClearPlayerRanks", tolua_cRankManager_ClearPlayerRanks); tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); tolua_function(tolua_S, "GetAllPlayers", tolua_cRankManager_GetAllPlayers); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 0f267473a..fd5e58025 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -1817,6 +1817,25 @@ bool cRankManager::SetDefaultRank(const AString & a_RankName) +void cRankManager::ClearPlayerRanks(void) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try { + SQLite::Statement stmt(m_DB, "DELETE FROM PlayerRank"); + stmt.exec(); + } + catch (SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove/clear all players: %s", __FUNCTION__, ex.what()); + } +} + + + + + bool cRankManager::UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName) { ASSERT(m_IsInitialized); diff --git a/src/RankManager.h b/src/RankManager.h index b577fad05..acfcdb01d 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -217,6 +217,10 @@ public: /** Returns the name of the default rank. */ const AString & GetDefaultRank(void) const { return m_DefaultRank; } + + /** Removes all player ranks from the database. Note that this doesn't change the cPlayer instances + for the already connected players, you need to update all the instances manually. */ + void ClearPlayerRanks(void); /** Updates the playername that is saved with this uuid. Returns false if a error occurred */ bool UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName); -- cgit v1.2.3 From f6979642e68dbbcb144ea376cc42a17dab8f3b37 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 28 Sep 2014 15:36:00 +0100 Subject: Use factory method to construct redstone simulator data --- src/Chunk.cpp | 2 +- src/Simulator/IncrementalRedstoneSimulator.inc | 5 +++++ src/Simulator/NoopRedstoneSimulator.h | 5 +++++ src/Simulator/RedstoneSimulator.h | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 3012f30b6..00cea4416 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -92,7 +92,7 @@ cChunk::cChunk( m_NeighborZP(a_NeighborZP), m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()), m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()), - m_RedstoneSimulatorData(NULL), + m_RedstoneSimulatorData(a_World->GetRedstoneSimulator ()->CreateChunkData()), m_AlwaysTicked(0) { if (a_NeighborXM != NULL) diff --git a/src/Simulator/IncrementalRedstoneSimulator.inc b/src/Simulator/IncrementalRedstoneSimulator.inc index 937e6b790..200fc0971 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.inc +++ b/src/Simulator/IncrementalRedstoneSimulator.inc @@ -27,6 +27,11 @@ public: { } ~cIncrementalRedstoneSimulator(); + + virtual cRedstoneSimulatorChunkData * CreateChunkData() override + { + return new cIncrementalRedstoneSimulatorChunkData; + } virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, ChunkType * a_Chunk) override; diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index 88e141e85..7c961f32b 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -36,5 +36,10 @@ public: UNUSED(a_BlockZ); UNUSED(a_Chunk); } + + virtual cRedstoneSimulatorChunkData * CreateChunkData() override + { + return NULL; + } } ; diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index f6d36f869..6104d39b4 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -24,5 +24,7 @@ public: super(a_World) { } + + virtual cRedstoneSimulatorChunkData * CreateChunkData() = 0; } ; -- cgit v1.2.3 From 80fe8d778973286397e91564a203521b8bfd3760 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 28 Sep 2014 17:57:01 +0100 Subject: Update Chunk.cpp --- src/Chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 00cea4416..96b8eda4e 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -92,7 +92,7 @@ cChunk::cChunk( m_NeighborZP(a_NeighborZP), m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()), m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()), - m_RedstoneSimulatorData(a_World->GetRedstoneSimulator ()->CreateChunkData()), + m_RedstoneSimulatorData(a_World->GetRedstoneSimulator()->CreateChunkData()), m_AlwaysTicked(0) { if (a_NeighborXM != NULL) -- cgit v1.2.3 From 4391b3fc0910e3e51f2b6a8bf6d319933a2cc8ad Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 28 Sep 2014 19:08:33 +0200 Subject: Fixed SetDefaultRank() return value. --- src/Bindings/ManualBindings_RankManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index cddf1ec2e..6e623af0d 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -975,7 +975,7 @@ static int tolua_cRankManager_SetDefaultRank(lua_State * L) // Set the rank, return the result: S.Push(cRoot::Get()->GetRankManager().SetDefaultRank(RankName)); - return 0; + return 1; } -- cgit v1.2.3 From 76e0c592ef2f9660f10ab099cb8e8cbffc35153b Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 28 Sep 2014 19:27:08 +0200 Subject: Added Granite, Diorite and Andesite to the NaturalPatches generator. --- src/Generating/ComposableGenerator.cpp | 27 +++++++++++++++++++++++++++ src/Generating/StructGen.cpp | 6 ++++-- src/Generating/StructGen.h | 11 ++++++----- 3 files changed, 37 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 69068d231..4efcd1284 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -428,6 +428,33 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) GravelVein.NestSize = 32; Ores.push_back(GravelVein); + // Granite vein + cStructGenOreNests::OreInfo GraniteVein; + GraniteVein.BlockType = E_BLOCK_STONE; + GraniteVein.BlockMeta = 1; + GraniteVein.MaxHeight = 127; + GraniteVein.NumNests = 20; + GraniteVein.NestSize = 32; + Ores.push_back(GraniteVein); + + // Diorite vein + cStructGenOreNests::OreInfo DioriteVein; + DioriteVein.BlockType = E_BLOCK_STONE; + DioriteVein.BlockMeta = 3; + DioriteVein.MaxHeight = 127; + DioriteVein.NumNests = 20; + DioriteVein.NestSize = 32; + Ores.push_back(DioriteVein); + + // Andesite vein + cStructGenOreNests::OreInfo AndesiteVein; + AndesiteVein.BlockType = E_BLOCK_STONE; + AndesiteVein.BlockMeta = 5; + AndesiteVein.MaxHeight = 127; + AndesiteVein.NumNests = 20; + AndesiteVein.NestSize = 32; + Ores.push_back(AndesiteVein); + m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 731324b0d..c23a72621 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -272,13 +272,14 @@ void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); cChunkDef::BlockTypes & BlockTypes = a_ChunkDesc.GetBlockTypes(); + cChunkDesc::BlockNibbleBytes & BlockMetas = a_ChunkDesc.GetBlockMetasUncompressed(); int seq = 1; // Generate the ores from the ore list. for (OreList::const_iterator itr = m_OreList.begin(); itr != m_OreList.end(); ++itr) { - GenerateOre(ChunkX, ChunkZ, itr->BlockType, itr->MaxHeight, itr->NumNests, itr->NestSize, BlockTypes, seq); + GenerateOre(ChunkX, ChunkZ, itr->BlockType, itr->BlockMeta, itr->MaxHeight, itr->NumNests, itr->NestSize, BlockTypes, BlockMetas, seq); seq++; } } @@ -287,7 +288,7 @@ void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) -void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq) +void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, NIBBLETYPE a_BlockMeta, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, cChunkDesc::BlockNibbleBytes & a_BlockMetas, int a_Seq) { // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other. // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes @@ -341,6 +342,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore if (a_BlockTypes[Index] == m_ToReplace) { a_BlockTypes[Index] = a_OreType; + a_BlockMetas[Index] = a_BlockMeta; } Num++; } // for z diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 55d5bc1c7..76bdf44d4 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -78,10 +78,11 @@ class cStructGenOreNests : public: struct OreInfo { - BLOCKTYPE BlockType; // The type of the nest. - int MaxHeight; // The highest possible a nest can occur - int NumNests; // How many nests per chunk - int NestSize; // The amount of blocks a nest can have. + BLOCKTYPE BlockType; // The type of the nest. + NIBBLETYPE BlockMeta = 0; // The block meta + int MaxHeight; // The highest possible a nest can occur + int NumNests; // How many nests per chunk + int NestSize; // The amount of blocks a nest can have. }; typedef std::vector OreList; @@ -103,7 +104,7 @@ protected: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); + void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, NIBBLETYPE a_BlockMeta, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, cChunkDesc::BlockNibbleBytes & a_BlockMetas, int a_Seq); } ; -- cgit v1.2.3 From 7c18681e092c905eafbcdcb7ecbd98ec13946502 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 28 Sep 2014 22:10:03 +0200 Subject: Fixed compilation --- src/Generating/StructGen.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 76bdf44d4..96aa3e437 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -79,10 +79,19 @@ public: struct OreInfo { BLOCKTYPE BlockType; // The type of the nest. - NIBBLETYPE BlockMeta = 0; // The block meta + NIBBLETYPE BlockMeta; // The block meta int MaxHeight; // The highest possible a nest can occur int NumNests; // How many nests per chunk int NestSize; // The amount of blocks a nest can have. + + OreInfo() : + BlockType(0), + BlockMeta(0), + MaxHeight(0), + NumNests(0), + NestSize(0) + { + } }; typedef std::vector OreList; -- cgit v1.2.3 From 5a44be13b7facbc3718b8cbc4eb76bbd50de085e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 28 Sep 2014 22:17:29 +0200 Subject: Fixed trailing whitespace. --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index bd00c0b9e..20e219309 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1153,7 +1153,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo if (a_OldBlock == E_BLOCK_BEDROCK) { Kick("You can't break a bedrock!"); - return; + return; } if (a_OldBlock == E_BLOCK_BARRIER) { -- cgit v1.2.3 From f8c627141ae930abfeb2a76599133a455bceaa9b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 28 Sep 2014 22:25:48 +0200 Subject: Protocol 1.8: Fixed possible crash on malformed packet. --- src/Protocol/Protocol18x.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 7a6eb5f28..625a29b7a 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1713,6 +1713,11 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { UInt32 NumBytesRead = m_ReceivedData.GetReadableSpace(); m_ReceivedData.ReadVarInt(CompressedSize); + if (CompressedSize > PacketLen) + { + m_Client->Kick("Bad compression"); + return; + } if (CompressedSize > 0) { // Decompress the data: -- cgit v1.2.3 From 488c6159df656e81cc90415d9f9026b34f1f1158 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 28 Sep 2014 22:27:23 +0200 Subject: Revert "1.8: Fixed plugin messages." This reverts commit 04ee8c43dd17eb98d1e3d66ff691898e9f269b95. --- src/Protocol/Protocol18x.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 625a29b7a..3985f5224 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -989,6 +989,7 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); + Pkt.WriteVarInt((UInt32)a_Message.size()); Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -2320,8 +2321,9 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); AString Data; - if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)) + if (!a_ByteBuffer.ReadString(Data, DataLen)) { return; } -- cgit v1.2.3 From 126b14aa09fcde7a54bc8a176b44f5f6c8f936c1 Mon Sep 17 00:00:00 2001 From: Jonathan Frederick Date: Sun, 28 Sep 2014 13:56:41 -0700 Subject: Make endermen take damage in water --- src/Mobs/Enderman.cpp | 20 ++++++++++++++++++++ src/Mobs/Enderman.h | 1 + 2 files changed, 21 insertions(+) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 51255beb3..fb372709a 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -181,3 +181,23 @@ bool cEnderman::CheckLight() return true; } + + + + + +void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + //TODO take damage in rain + + //Take damage when touching water, drowning damage seems to be most appropriate + if (IsSwimming()) + { + EventLosePlayer(); + TakeDamage(dtDrowning, NULL, 1, 0); + //TODO teleport to a safe location + } + +} diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index 4583746e7..947c32b96 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -21,6 +21,7 @@ public: virtual void CheckEventSeePlayer(void) override; virtual void CheckEventLostPlayer(void) override; virtual void EventLosePlayer(void) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3 From 280831df264fe34a771fa16593e860037c5b4444 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 28 Sep 2014 23:03:44 +0200 Subject: Plugin messages: Vanilla prefixes its payloads with VarInt lengths. --- src/Protocol/Protocol18x.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 3985f5224..1070a8434 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -989,7 +989,10 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); - Pkt.WriteVarInt((UInt32)a_Message.size()); + if (a_Channel.substr(0, 3) == "MC|") + { + Pkt.WriteVarInt((UInt32)a_Message.size()); + } Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -2321,12 +2324,18 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); AString Data; - if (!a_ByteBuffer.ReadString(Data, DataLen)) + if (Channel.substr(0, 3) == "MC|") { - return; + // Vanilla sends the payload length within the payload itself, so skip it: + HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); + if (DataLen != a_ByteBuffer.GetReadableSpace() - 1) + { + ASSERT(!"Bad plugin message payload length"); + return; + } } + a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); // Always succeeds m_Client->HandlePluginMessage(Channel, Data); } -- cgit v1.2.3 From 7a61e1e6040e7df5e5e928a619b5828b8eff556e Mon Sep 17 00:00:00 2001 From: Jonathan Frederick Date: Sun, 28 Sep 2014 19:24:47 -0700 Subject: Fix comments --- src/Mobs/Enderman.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index fb372709a..ffc24e56b 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -190,9 +190,9 @@ void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - //TODO take damage in rain + // TODO take damage in rain - //Take damage when touching water, drowning damage seems to be most appropriate + // Take damage when touching water, drowning damage seems to be most appropriate if (IsSwimming()) { EventLosePlayer(); -- cgit v1.2.3 From c02711633dd3491242ba5d73148bb9289db04ebf Mon Sep 17 00:00:00 2001 From: Jonathan Frederick Date: Sun, 28 Sep 2014 19:27:53 -0700 Subject: Derp --- src/Mobs/Enderman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index ffc24e56b..567714382 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -197,7 +197,7 @@ void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) { EventLosePlayer(); TakeDamage(dtDrowning, NULL, 1, 0); - //TODO teleport to a safe location + // TODO teleport to a safe location } } -- cgit v1.2.3 From 0b438b5fe8552f72ca04c25592a1ecb8cf3adcbe Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 29 Sep 2014 13:12:50 +0200 Subject: Added torches placeable on upside-down-halfslaps --- src/Blocks/BlockTorch.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index fa46b37a8..bdb3e9914 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -124,7 +124,9 @@ public: ((BlockInQuestion == E_BLOCK_GLASS) || (BlockInQuestion == E_BLOCK_FENCE) || (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) && + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB)) && (Face == BLOCK_FACE_TOP) ) { -- cgit v1.2.3 From f014d8764b0591c6216af6ff9ea2a0d89c0dc4b3 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 29 Sep 2014 13:17:24 +0200 Subject: Update BlockTorch.h --- src/Blocks/BlockTorch.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index bdb3e9914..0aabcdf67 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -124,9 +124,9 @@ public: ((BlockInQuestion == E_BLOCK_GLASS) || (BlockInQuestion == E_BLOCK_FENCE) || (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB)) && + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB)) && (Face == BLOCK_FACE_TOP) ) { -- cgit v1.2.3 From ff3a3b801d5fa6edb855b13b73af497b29e8a42e Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 29 Sep 2014 14:43:16 +0200 Subject: Renamed GetAllPlayers() to GetAllPlayerUUIDs() --- src/Bindings/ManualBindings_RankManager.cpp | 10 +++++----- src/RankManager.cpp | 2 +- src/RankManager.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 6e623af0d..3c58a0a92 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -204,11 +204,11 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) -/** Binds cRankManager::GetAllPlayers */ -static int tolua_cRankManager_GetAllPlayers(lua_State * L) +/** Binds cRankManager::GetAllPlayerUUIDs */ +static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L) { // Function signature: - // cRankManager:GetAllPlayers() -> arraytable of Player UUID's + // cRankManager:GetAllPlayerUUIDs() -> arraytable of Player UUID's cLuaState S(L); if ( @@ -220,7 +220,7 @@ static int tolua_cRankManager_GetAllPlayers(lua_State * L) } // Get the player uuid's: - AStringVector Players = cRoot::Get()->GetRankManager().GetAllPlayers(); + AStringVector Players = cRoot::Get()->GetRankManager().GetAllPlayerUUIDs(); // Push the results: S.Push(Players); @@ -1055,7 +1055,7 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) tolua_function(tolua_S, "ClearPlayerRanks", tolua_cRankManager_ClearPlayerRanks); tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); - tolua_function(tolua_S, "GetAllPlayers", tolua_cRankManager_GetAllPlayers); + tolua_function(tolua_S, "GetAllPlayerUUIDs", tolua_cRankManager_GetAllPlayerUUIDs); tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); tolua_function(tolua_S, "GetDefaultRank", tolua_cRankManager_GetDefaultRank); tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); diff --git a/src/RankManager.cpp b/src/RankManager.cpp index fd5e58025..c9b428e3b 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -663,7 +663,7 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) -AStringVector cRankManager::GetAllPlayers(void) +AStringVector cRankManager::GetAllPlayerUUIDs(void) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); diff --git a/src/RankManager.h b/src/RankManager.h index acfcdb01d..3f5884f2e 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -84,7 +84,7 @@ public: AStringVector GetRankPermissions(const AString & a_RankName); /** Returns the short uuids of all defined players. */ - AStringVector GetAllPlayers(void); + AStringVector GetAllPlayerUUIDs(void); /** Returns the names of all defined ranks. */ AStringVector GetAllRanks(void); -- cgit v1.2.3 From 6127c21af97e450037daecd981cc88f40c3af423 Mon Sep 17 00:00:00 2001 From: netchip Date: Mon, 29 Sep 2014 17:18:20 +0200 Subject: BlockStone: drop the right cobblestone on onBreak(). Signed-off-by: netchip --- src/BlockID.h | 6 ++++++ src/Blocks/BlockStone.h | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 45e71d85d..80b5700a8 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -652,6 +652,12 @@ enum E_META_STAINED_GLASS_PANE_RED = 14, E_META_STAINED_GLASS_PANE_BLACK = 15, + // E_BLOCK_STONE metas: + E_META_STONE = 0, + E_META_STONE_GRANITE = 1, + E_META_STONE_DIORITE = 3, + E_META_STONE_ANDESITE = 5, + // E_BLOCK_STONE_SLAB metas: E_META_STONE_SLAB_STONE = 0, E_META_STONE_SLAB_SANDSTONE = 1, diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h index cd5230f49..2b71cebf1 100644 --- a/src/Blocks/BlockStone.h +++ b/src/Blocks/BlockStone.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" - +#include "BlockID.h" @@ -18,9 +18,15 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); + switch(a_BlockMeta) { + case E_META_STONE: + a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); + break; + default: + a_Pickups.push_back(cItem(E_BLOCK_STONE, 1, a_BlockMeta)); + } } -} ; +}; -- cgit v1.2.3 From d5ae659da389c1a7a67c92a9202182d4f243b2eb Mon Sep 17 00:00:00 2001 From: w00tc0d3 Date: Mon, 29 Sep 2014 17:35:30 +0200 Subject: Tabs -> spaces --- src/BlockID.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 80b5700a8..9a8830710 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -653,10 +653,10 @@ enum E_META_STAINED_GLASS_PANE_BLACK = 15, // E_BLOCK_STONE metas: - E_META_STONE = 0, - E_META_STONE_GRANITE = 1, - E_META_STONE_DIORITE = 3, - E_META_STONE_ANDESITE = 5, + E_META_STONE = 0, + E_META_STONE_GRANITE = 1, + E_META_STONE_DIORITE = 3, + E_META_STONE_ANDESITE = 5, // E_BLOCK_STONE_SLAB metas: E_META_STONE_SLAB_STONE = 0, -- cgit v1.2.3 From 9628733df2ab39668bf1e92571442b1486d9d9de Mon Sep 17 00:00:00 2001 From: w00tc0d3 Date: Mon, 29 Sep 2014 19:19:17 +0200 Subject: BlockStone.h: fix the codestyle --- src/Blocks/BlockStone.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h index 2b71cebf1..2e7801f8e 100644 --- a/src/Blocks/BlockStone.h +++ b/src/Blocks/BlockStone.h @@ -18,13 +18,12 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - switch(a_BlockMeta) { - case E_META_STONE: - a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); - break; - default: - a_Pickups.push_back(cItem(E_BLOCK_STONE, 1, a_BlockMeta)); + if(a_BlockMeta == E_META_STONE) + { + a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); + return; } + a_Pickups.push_back(cItem(E_BLOCK_STONE, 1, a_BlockMeta)); } }; -- cgit v1.2.3 From bdb8d916c0ed886e739be397f1aefc1ad2ae1940 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 29 Sep 2014 19:45:12 +0100 Subject: Fixed codestyle again. --- src/Blocks/BlockStone.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h index 2e7801f8e..e52599c0f 100644 --- a/src/Blocks/BlockStone.h +++ b/src/Blocks/BlockStone.h @@ -18,7 +18,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - if(a_BlockMeta == E_META_STONE) + if (a_BlockMeta == E_META_STONE) { a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); return; -- cgit v1.2.3 From 30b083ed63b598dd26802682492d060d4d93921c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 29 Sep 2014 21:34:15 +0200 Subject: World: Fixed chunk generation by plugins. ChunkWorx was broken, it was trying to generate chunks that were not properly marked as InQueue. --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index 61c061867..6059b841f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3003,7 +3003,7 @@ void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ) void cWorld::GenerateChunk(int a_ChunkX, int a_ChunkZ) { - m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ, false); + m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkZ); } -- cgit v1.2.3 From aae90c2cf0d670ab4be05c0e7f09b00523b3b823 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 29 Sep 2014 21:38:11 +0200 Subject: Style fixes. --- src/Blocks/BlockTorch.h | 14 ++++++++------ src/Protocol/ProtocolRecognizer.cpp | 6 +++--- src/RankManager.cpp | 3 ++- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 0aabcdf67..eb201dd05 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -121,12 +121,14 @@ public: // If on a block that can only hold a torch if torch is standing on it, return that face if ( - ((BlockInQuestion == E_BLOCK_GLASS) || - (BlockInQuestion == E_BLOCK_FENCE) || - (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB)) && + ( + (BlockInQuestion == E_BLOCK_GLASS) || + (BlockInQuestion == E_BLOCK_FENCE) || + (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB) + ) && (Face == BLOCK_FACE_TOP) ) { diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index ef6802d2b..4f8eb59db 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -201,9 +201,9 @@ void cProtocolRecognizer::SendDisconnect(const AString & a_Reason) SendData((const char *)&Packet, 1); // WriteByte() AString UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length()); - static const short Size = htons((short)(UTF16.size() / 2)); - SendData((const char *)&Size, 2); // WriteShort() - SendData(UTF16.data(), UTF16.size()); // WriteString() + static const u_short Size = htons((u_short)(UTF16.size() / 2)); + SendData((const char *)&Size, 2); // WriteShort() + SendData(UTF16.data(), UTF16.size()); // WriteString() } } diff --git a/src/RankManager.cpp b/src/RankManager.cpp index c9b428e3b..4abe8d1e1 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -1822,7 +1822,8 @@ void cRankManager::ClearPlayerRanks(void) ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - try { + try + { SQLite::Statement stmt(m_DB, "DELETE FROM PlayerRank"); stmt.exec(); } -- cgit v1.2.3 From 33dc66a4d23246b5794cf9ca5bd4287a72db4cec Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 29 Sep 2014 22:00:14 +0200 Subject: RankMgr: GetAllPlayers() returns players sorted by name. --- src/RankManager.cpp | 2 +- src/RankManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 4abe8d1e1..f5342ed3d 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -671,7 +671,7 @@ AStringVector cRankManager::GetAllPlayerUUIDs(void) AStringVector res; try { - SQLite::Statement stmt(m_DB, "SELECT PlayerUUID FROM PlayerRank"); + SQLite::Statement stmt(m_DB, "SELECT PlayerUUID FROM PlayerRank ORDER BY PlayerName COLLATE NOCASE"); while (stmt.executeStep()) { res.push_back(stmt.getColumn(0).getText()); diff --git a/src/RankManager.h b/src/RankManager.h index 3f5884f2e..61c52fda6 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -83,7 +83,7 @@ public: Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankPermissions(const AString & a_RankName); - /** Returns the short uuids of all defined players. */ + /** Returns the short uuids of all defined players. The returned players are ordered by their name (NOT their UUIDs). */ AStringVector GetAllPlayerUUIDs(void); /** Returns the names of all defined ranks. */ -- cgit v1.2.3 From d731ad37b15c735a66de9c92f9125c99ca3aaf50 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Tue, 30 Sep 2014 12:43:48 +0200 Subject: actual solving of the halfslap+torch problem --- src/Blocks/BlockTorch.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index eb201dd05..3280aef36 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -165,7 +165,9 @@ public: (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB) ) { // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' -- cgit v1.2.3 From b2cf4004f8e198d4528981468e59ba276bffe986 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Tue, 30 Sep 2014 12:45:44 +0200 Subject: Set right indentation --- src/Blocks/BlockTorch.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 3280aef36..f7973a607 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -165,9 +165,9 @@ public: (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB) ) { // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' -- cgit v1.2.3 From d7066f43d3fd592457e69a46f0fed098c80b3190 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 30 Sep 2014 13:33:57 +0200 Subject: Rewritten plugin messages, vanilla are being parsed directly. This should finally fix the compatibility problems between 1.7 and 1.8 protocols with the changes in the vanilla plugin messages. --- src/ClientHandle.cpp | 120 +++++++++++-------------------------------- src/ClientHandle.h | 55 ++++++++++++++------ src/Protocol/Protocol17x.cpp | 92 +++++++++++++++++++++++++++++++++ src/Protocol/Protocol17x.h | 3 ++ src/Protocol/Protocol18x.cpp | 86 ++++++++++++++++++++++++++----- src/Protocol/Protocol18x.h | 4 ++ 6 files changed, 242 insertions(+), 118 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 20e219309..a29bef0c0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -551,6 +551,16 @@ void cClientHandle::RemoveFromAllChunks() +void cClientHandle::HandleNPCTrade(int a_SlotNum) +{ + // TODO + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + + void cClientHandle::HandlePing(void) { // Somebody tries to retrieve information about the server @@ -573,7 +583,6 @@ void cClientHandle::HandlePing(void) bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Username) { - LOGD("LOGIN %s", a_Username.c_str()); m_Username = a_Username; if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) @@ -676,25 +685,7 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message) { - if (a_Channel == "MC|AdvCdm") - { - // Command block, set text, Client -> Server - HandleCommandBlockMessage(a_Message.c_str(), a_Message.size()); - } - else if (a_Channel == "MC|Brand") - { - // Client <-> Server branding exchange - SendPluginMessage("MC|Brand", "MCServer"); - } - else if (a_Channel == "MC|Beacon") - { - HandleBeaconSelection(a_Message.c_str(), a_Message.size()); - } - else if (a_Channel == "MC|ItemName") - { - HandleAnvilItemName(a_Message.c_str(), a_Message.size()); - } - else if (a_Channel == "REGISTER") + if (a_Channel == "REGISTER") { if (HasPluginChannel(a_Channel)) { @@ -777,15 +768,8 @@ void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList -void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) +void cClientHandle::HandleBeaconSelection(int a_PrimaryEffect, int a_SecondaryEffect) { - if (a_Length < 14) - { - SendChat("Failure setting beacon selection; bad request", mtFailure); - LOGD("Malformed MC|Beacon packet."); - return; - } - cWindow * Window = m_Player->GetWindow(); if ((Window == NULL) || (Window->GetWindowType() != cWindow::wtBeacon)) { @@ -798,23 +782,15 @@ void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) return; } - cByteBuffer Buffer(a_Length); - Buffer.Write(a_Data, a_Length); - - int PrimaryEffectID, SecondaryEffectID; - Buffer.ReadBEInt(PrimaryEffectID); - Buffer.ReadBEInt(SecondaryEffectID); - cEntityEffect::eType PrimaryEffect = cEntityEffect::effNoEffect; - if ((PrimaryEffectID >= 0) && (PrimaryEffectID <= (int)cEntityEffect::effSaturation)) + if ((a_PrimaryEffect >= 0) && (a_PrimaryEffect <= (int)cEntityEffect::effSaturation)) { - PrimaryEffect = (cEntityEffect::eType)PrimaryEffectID; + PrimaryEffect = (cEntityEffect::eType)a_PrimaryEffect; } - cEntityEffect::eType SecondaryEffect = cEntityEffect::effNoEffect; - if ((SecondaryEffectID >= 0) && (SecondaryEffectID <= (int)cEntityEffect::effSaturation)) + if ((a_SecondaryEffect >= 0) && (a_SecondaryEffect <= (int)cEntityEffect::effSaturation)) { - SecondaryEffect = (cEntityEffect::eType)SecondaryEffectID; + SecondaryEffect = (cEntityEffect::eType)a_SecondaryEffect; } Window->SetSlot(*m_Player, 0, cItem()); @@ -841,52 +817,12 @@ void cClientHandle::HandleBeaconSelection(const char * a_Data, size_t a_Length) -void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Length) +void cClientHandle::HandleCommandBlockBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_NewCommand) { - if (a_Length < 14) - { - SendChat("Failure setting command block command; bad request", mtFailure); - LOGD("Malformed MC|AdvCdm packet."); - return; - } - - cByteBuffer Buffer(a_Length); - Buffer.Write(a_Data, a_Length); - - int BlockX, BlockY, BlockZ; - - AString Command; - - char Mode; - - Buffer.ReadChar(Mode); - - switch (Mode) - { - case 0x00: - { - Buffer.ReadBEInt(BlockX); - Buffer.ReadBEInt(BlockY); - Buffer.ReadBEInt(BlockZ); - - Buffer.ReadVarUTF8String(Command); - break; - } - - default: - { - SendChat("Failure setting command block command; unhandled mode", mtFailure); - LOGD("Unhandled MC|AdvCdm packet mode."); - return; - } - } - cWorld * World = m_Player->GetWorld(); - if (World->AreCommandBlocksEnabled()) { - World->SetCommandBlockCommand(BlockX, BlockY, BlockZ, Command); - + World->SetCommandBlockCommand(a_BlockX, a_BlockY, a_BlockZ, a_NewCommand); SendChat("Successfully set command block command", mtSuccess); } else @@ -899,22 +835,26 @@ void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Leng -void cClientHandle::HandleAnvilItemName(const char * a_Data, size_t a_Length) +void cClientHandle::HandleCommandBlockEntityChange(int a_EntityID, const AString & a_NewCommand) { - if (a_Length < 1) - { - return; - } + // TODO + LOGWARNING("%s: Not implemented yet", __FUNCTION__); +} + + + + +void cClientHandle::HandleAnvilItemName(const AString & a_ItemName) +{ if ((m_Player->GetWindow() == NULL) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtAnvil)) { return; } - AString Name(a_Data, a_Length); - if (Name.length() <= 30) + if (a_ItemName.length() <= 30) { - ((cAnvilWindow *)m_Player->GetWindow())->SetRepairedItemName(Name, m_Player); + ((cAnvilWindow *)m_Player->GetWindow())->SetRepairedItemName(a_ItemName, m_Player); } } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 10cf6ae28..1f22762c0 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -222,6 +222,13 @@ public: bool HasPluginChannel(const AString & a_PluginChannel); + /** Called by the protocol when it receives the MC|Brand plugin message. Also callable by plugins. + Simply stores the string value. */ + void SetClientBrand(const AString & a_ClientBrand) { m_ClientBrand = a_ClientBrand; } + + /** Returns the client brand received in the MC|Brand plugin message or set by a plugin. */ + const AString & GetClientBrand(void) const { return m_ClientBrand; } + // tolua_end /** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */ @@ -236,12 +243,31 @@ public: void PacketError(unsigned char a_PacketType); // Calls that cProtocol descendants use for handling packets: - void HandleAnimation (char a_Animation); - void HandleChat (const AString & a_Message); - void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem); - void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching); - void HandleEntityLeaveBed (int a_EntityID); - void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); + void HandleAnimation(char a_Animation); + + /** Called when the protocol receives a MC|ItemName plugin message, indicating that the player named + an item in the anvil UI. */ + void HandleAnvilItemName(const AString & a_ItemName); + + /** Called when the protocol receives a MC|Beacon plugin message, indicating that the player set an effect + in the beacon UI. */ + void HandleBeaconSelection(int a_PrimaryEffect, int a_SecondaryEffect); + + /** Called when the protocol detects a chat packet. */ + void HandleChat(const AString & a_Message); + + /** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new + command in the command block UI, for a block-based commandblock. */ + void HandleCommandBlockBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_NewCommand); + + /** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new + command in the command block UI, for an entity-based commandblock (minecart?). */ + void HandleCommandBlockEntityChange(int a_EntityID, const AString & a_NewCommand); + + void HandleCreativeInventory (short a_SlotNum, const cItem & a_HeldItem); + void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching); + void HandleEntityLeaveBed (int a_EntityID); + void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). @@ -251,6 +277,11 @@ public: void HandleKeepAlive (int a_KeepAliveID); void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status); + + /** Called when the protocol receives a MC|TrSel packet, indicating that the player used a trade in + the NPC UI. */ + void HandleNPCTrade(int a_SlotNum); + void HandlePing (void); void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); @@ -392,6 +423,9 @@ private: /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; + + /** The brand identification of the client, as received in the MC|Brand plugin message or set from a plugin. */ + AString m_ClientBrand; /** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */ @@ -421,15 +455,6 @@ private: /** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */ void UnregisterPluginChannels(const AStringVector & a_ChannelList); - /** Handles the "MC|Beacon" plugin message */ - void HandleBeaconSelection(const char * a_Data, size_t a_Length); - - /** Handles the "MC|AdvCdm" plugin message */ - void HandleCommandBlockMessage(const char * a_Data, size_t a_Length); - - /** Handles the "MC|ItemName" plugin message */ - void HandleAnvilItemName(const char * a_Data, size_t a_Length); - // cSocketThreads::cCallback overrides: virtual bool DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index e4c33908a..07338f395 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2064,6 +2064,22 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length); + if (Length + 1 != (int)a_ByteBuffer.GetReadableSpace()) + { + LOGD("Invalid plugin message packet, payload length doesn't match packet length (exp %d, got %d)", + (int)a_ByteBuffer.GetReadableSpace() - 1, Length + ); + return; + } + + // If the plugin channel is recognized vanilla, handle it directly: + if (Channel.substr(0, 3) == "MC|") + { + HandleVanillaPluginMessage(a_ByteBuffer, Channel, Length); + return; + } + + // Read the plugin message and relay to clienthandle: AString Data; if (!a_ByteBuffer.ReadString(Data, Length)) { @@ -2217,6 +2233,82 @@ void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) +void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, short a_PayloadLength) +{ + if (a_Channel == "MC|AdvCdm") + { + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode) + switch (Mode) + { + case 0x00: + { + // Block-based commandblock update: + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command); + m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command); + break; + } + + // TODO: Entity-based commandblock update + + default: + { + m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %d", Mode), mtFailure); + LOG("Unhandled MC|AdvCdm packet mode."); + return; + } + } // switch (Mode) + return; + } + else if (a_Channel == "MC|Brand") + { + // Read the client's brand: + AString Brand; + if (a_ByteBuffer.ReadString(Brand, a_PayloadLength)) + { + m_Client->SetClientBrand(Brand); + } + + // Send back our brand: + SendPluginMessage("MC|Brand", "MCServer"); + return; + } + else if (a_Channel == "MC|Beacon") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect1); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect2); + m_Client->HandleBeaconSelection(Effect1, Effect2); + return; + } + else if (a_Channel == "MC|ItemName") + { + AString ItemName; + if (a_ByteBuffer.ReadString(ItemName, a_PayloadLength)) + { + m_Client->HandleAnvilItemName(ItemName); + } + return; + } + else if (a_Channel == "MC|TrSel") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, SlotNum); + m_Client->HandleNPCTrade(SlotNum); + return; + } + LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); + + // Read the payload and send it through to the clienthandle: + AString Message; + VERIFY(a_ByteBuffer.ReadString(Message, a_PayloadLength)); + m_Client->HandlePluginMessage(a_Channel, Message); +} + + + + + void cProtocol172::SendData(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 0bc86a72a..7709df59d 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -295,6 +295,9 @@ protected: void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); + /** Parses Vanilla plugin messages into specific ClientHandle calls. + The message payload is still in the bytebuffer, to be read by this function. */ + void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, short a_PayloadLength); /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 1070a8434..acdb48cf7 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -989,10 +989,6 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); - if (a_Channel.substr(0, 3) == "MC|") - { - Pkt.WriteVarInt((UInt32)a_Message.size()); - } Pkt.WriteBuf(a_Message.data(), a_Message.size()); } @@ -2324,18 +2320,17 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - AString Data; + + // If the plugin channel is recognized vanilla, handle it directly: if (Channel.substr(0, 3) == "MC|") { - // Vanilla sends the payload length within the payload itself, so skip it: - HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen); - if (DataLen != a_ByteBuffer.GetReadableSpace() - 1) - { - ASSERT(!"Bad plugin message payload length"); - return; - } + HandleVanillaPluginMessage(a_ByteBuffer, Channel); + return; } - a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); // Always succeeds + + // Read the plugin message and relay to clienthandle: + AString Data; + VERIFY(a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)); // Always succeeds m_Client->HandlePluginMessage(Channel, Data); } @@ -2524,6 +2519,71 @@ void cProtocol180::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer) +void cProtocol180::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel) +{ + if (a_Channel == "MC|AdvCdm") + { + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode) + switch (Mode) + { + case 0x00: + { + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command); + m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command); + break; + } + + default: + { + m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %d", Mode), mtFailure); + LOG("Unhandled MC|AdvCdm packet mode."); + return; + } + } // switch (Mode) + return; + } + else if (a_Channel == "MC|Brand") + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand); + m_Client->SetClientBrand(Brand); + // Send back our brand, including the length: + SendPluginMessage("MC|Brand", "\x08MCServer"); + return; + } + else if (a_Channel == "MC|Beacon") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect1); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect2); + m_Client->HandleBeaconSelection(Effect1, Effect2); + return; + } + else if (a_Channel == "MC|ItemName") + { + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, ItemName); + m_Client->HandleAnvilItemName(ItemName); + return; + } + else if (a_Channel == "MC|TrSel") + { + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, SlotNum); + m_Client->HandleNPCTrade(SlotNum); + return; + } + LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); + + // Read the payload and send it through to the clienthandle: + AString Message; + VERIFY(a_ByteBuffer.ReadString(Message, a_ByteBuffer.GetReadableSpace() - 1)); + m_Client->HandlePluginMessage(a_Channel, Message); +} + + + + + void cProtocol180::SendData(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index acc167a6d..8c0b77a21 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -312,6 +312,10 @@ protected: void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); + /** Parses Vanilla plugin messages into specific ClientHandle calls. + The message payload is still in the bytebuffer, the handler reads it specifically for each handled channel */ + void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel); + /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; -- cgit v1.2.3 From b77480b4ef83e131d1c0c59409ec284a1040dab1 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Tue, 30 Sep 2014 14:05:23 +0200 Subject: Indentation --- src/Blocks/BlockTorch.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index f7973a607..dd252f2a4 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -165,9 +165,9 @@ public: (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) + (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || + (BlockInQuestion == E_BLOCK_STONE_SLAB) || + (BlockInQuestion == E_BLOCK_WOODEN_SLAB) ) { // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' -- cgit v1.2.3 From 5111628ba5b60aa5c9191ff6a09573920ac50e9c Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 30 Sep 2014 19:49:42 +0200 Subject: Fixed 1.8 doors. --- src/Blocks/BlockDoor.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 0ff8bcfc8..7e46feec4 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -173,7 +173,20 @@ public: /** Returns true if the specified blocktype is any kind of door */ inline static bool IsDoor(BLOCKTYPE a_Block) { - return (a_Block == E_BLOCK_WOODEN_DOOR) || (a_Block == E_BLOCK_IRON_DOOR); + switch (a_Block) + { + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_WOODEN_DOOR: + { + return true; + } + } + return false; } -- cgit v1.2.3 From 83973520c8492225e5ea02ebfd0a5d47b7e35f85 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 30 Sep 2014 20:04:49 +0200 Subject: Fixed iron trapdoors --- src/BlockInfo.cpp | 1 + src/Blocks/BlockTrapdoor.h | 5 +++++ src/Simulator/SandSimulator.cpp | 1 + src/World.cpp | 4 ++-- 4 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 14e814084..719ba0550 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -329,6 +329,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PistonBreakable = true; a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_LILY_PAD ].m_PistonBreakable = true; diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 41256ae55..d3f3c9a38 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -29,6 +29,11 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { + if (m_BlockType == E_BLOCK_IRON_TRAPDOOR) + { + return; + } + // Flip the ON bit on/off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index e8887ce59..aad41e463 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -160,6 +160,7 @@ bool cSandSimulator::CanContinueFallThrough(BLOCKTYPE a_BlockType) case E_BLOCK_FIRE: case E_BLOCK_FLOWER_POT: case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_IRON_TRAPDOOR: case E_BLOCK_LAVA: case E_BLOCK_LEVER: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: diff --git a/src/World.cpp b/src/World.cpp index 6059b841f..a3c804b44 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2954,7 +2954,7 @@ bool cWorld::IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ) BLOCKTYPE Block; NIBBLETYPE Meta; GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if (Block != E_BLOCK_TRAPDOOR) + if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR)) { return false; } @@ -2971,7 +2971,7 @@ bool cWorld::SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Op BLOCKTYPE Block; NIBBLETYPE Meta; GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if (Block != E_BLOCK_TRAPDOOR) + if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR)) { return false; } -- cgit v1.2.3 From e74510bddf41ab4f92e9255ea0be2786ef1e621b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 30 Sep 2014 20:27:20 +0200 Subject: Fixed a missing semicolon. --- src/Protocol/Protocol17x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 07338f395..a7abd240f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2237,7 +2237,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const { if (a_Channel == "MC|AdvCdm") { - HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode) + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode); switch (Mode) { case 0x00: -- cgit v1.2.3 From 425df6b69490e29b367c62476a125aa84bbcbcc5 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 30 Sep 2014 20:31:27 +0200 Subject: Fixed 1.8 dirt types --- src/BlockID.h | 1 + src/Blocks/BlockDirt.h | 10 +++++++++- src/Items/ItemHoe.h | 27 +++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 9a8830710..03a7f63e6 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -477,6 +477,7 @@ enum // E_BLOCK_DIRT metas: E_META_DIRT_NORMAL = 0, E_META_DIRT_GRASSLESS = 1, + E_META_DIRT_COARSE = 1, E_META_DIRT_PODZOL = 2, // E_BLOCK_DISPENSER / E_BLOCK_DROPPER metas: diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 60d81db72..b6d762dcf 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -21,7 +21,15 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); + if (a_BlockMeta == E_META_DIRT_COARSE) + { + // Drop the coarse block (dirt, meta 1) + a_Pickups.Add(E_BLOCK_DIRT, 1, 1); + } + else + { + a_Pickups.Add(E_BLOCK_DIRT, 1, 0); + } } diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index de8b9a061..ae3723323 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -24,12 +24,35 @@ public: { return false; } - BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); BLOCKTYPE UpperBlock = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); + BLOCKTYPE Block; + NIBBLETYPE BlockMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, BlockMeta); + if (((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) && (UpperBlock == E_BLOCK_AIR)) { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); + BLOCKTYPE NewBlock = E_BLOCK_FARMLAND; + if (Block == E_BLOCK_DIRT) + { + switch (BlockMeta) + { + case E_META_DIRT_COARSE: + { + // Transform to normal dirt + NewBlock = E_BLOCK_DIRT; + break; + } + case E_META_DIRT_PODZOL: + { + // You can't transform this block with a hoe in vanilla + return false; + } + default: break; + } + } + + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, NewBlock, 0); a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f); a_Player->UseEquippedItem(); return true; -- cgit v1.2.3 From 7d3016c7adc1a2d88447acfaf6c642ab25028a35 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 30 Sep 2014 20:59:59 +0200 Subject: Code improvements --- src/Blocks/BlockDirt.h | 4 ++-- src/Blocks/BlockDoor.h | 5 ++++- src/Blocks/BlockTrapdoor.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index b6d762dcf..19f889372 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -24,11 +24,11 @@ public: if (a_BlockMeta == E_META_DIRT_COARSE) { // Drop the coarse block (dirt, meta 1) - a_Pickups.Add(E_BLOCK_DIRT, 1, 1); + a_Pickups.Add(E_BLOCK_DIRT, 1, E_META_DIRT_COARSE); } else { - a_Pickups.Add(E_BLOCK_DIRT, 1, 0); + a_Pickups.Add(E_BLOCK_DIRT, 1, E_META_DIRT_NORMAL); } } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 7e46feec4..92ad8da12 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -185,8 +185,11 @@ public: { return true; } + default: + { + return false; + } } - return false; } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index d3f3c9a38..8c96de0f1 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -31,6 +31,7 @@ public: { if (m_BlockType == E_BLOCK_IRON_TRAPDOOR) { + // Iron doors can only be toggled by redstone, not by right-clicking return; } -- cgit v1.2.3 From 48c99dcd2ec972ebf627aa0b4d64a0e484d47aa5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 30 Sep 2014 22:00:33 +0100 Subject: Improved torch handler --- src/BlockInfo.cpp | 1 + src/Blocks/BlockTorch.h | 121 ++++++++++++++++++++---------------------------- 2 files changed, 52 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 14e814084..05a1e13f8 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -527,6 +527,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_MOB_SPAWNER ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index dd252f2a4..3070adfd9 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -24,32 +24,22 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - // Find proper placement of torch + BLOCKTYPE Block; + NIBBLETYPE Meta; + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) + if (!CanBePlacedOn(Block, Meta, a_BlockFace)) // Try to preserve original direction { - a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face + // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face + + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block + a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Set a_BlockFace to a valid direction which will be converted later to a metadata if (a_BlockFace == BLOCK_FACE_NONE) { - // Client wouldn't have sent anything anyway, but whatever return false; } } - else - { - // Not top or bottom faces, try to preserve whatever face was clicked - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block - if (!CanBePlacedOn(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace)) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block - // Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face - a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (a_BlockFace == BLOCK_FACE_NONE) - { - return false; - } - } - } a_BlockType = m_BlockType; a_BlockMeta = DirectionToMetaData(a_BlockFace); @@ -97,15 +87,40 @@ public: } - static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace) + static bool CanBePlacedOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_BlockFace) { - if (!cBlockInfo::FullyOccupiesVoxel(a_BlockType)) - { - return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle - } - else + switch (a_BlockType) { - return true; + case E_BLOCK_END_PORTAL_FRAME: + case E_BLOCK_SOULSAND: + { + // Exceptional vanilla behaviour + return true; + } + case E_BLOCK_GLASS: + case E_BLOCK_STAINED_GLASS: + case E_BLOCK_FENCE: + case E_BLOCK_NETHER_BRICK_FENCE: + case E_BLOCK_COBBLESTONE_WALL: + { + // Torches can only be placed on top of these blocks + return (a_BlockFace == BLOCK_FACE_YP); + } + case E_BLOCK_STONE_SLAB: + case E_BLOCK_WOODEN_SLAB: + { + // Toches can be placed on the top of these slabs only if the occupy the top half of the voxel + return ((a_BlockFace == BLOCK_FACE_YP) && ((a_BlockMeta & 0x08) == 0x08)); + } + default: + { + if (cBlockInfo::FullyOccupiesVoxel(a_BlockType)) + { + // Torches can be placed on full blocks unless their bottom side is clicked + return (a_BlockFace != BLOCK_FACE_YM); + } + return false; + } } } @@ -117,26 +132,12 @@ public: { eBlockFace Face = static_cast(i); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true); - BLOCKTYPE BlockInQuestion = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - - // If on a block that can only hold a torch if torch is standing on it, return that face - if ( - ( - (BlockInQuestion == E_BLOCK_GLASS) || - (BlockInQuestion == E_BLOCK_FENCE) || - (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) - ) && - (Face == BLOCK_FACE_TOP) - ) - { - return Face; - } - else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM)) + BLOCKTYPE BlockInQuestion; + NIBBLETYPE BlockInQuestionMeta; + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockInQuestion, BlockInQuestionMeta); + + if (CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face)) { - // Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face return Face; } else @@ -152,36 +153,16 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { eBlockFace Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); - AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true); + BLOCKTYPE BlockInQuestion; - a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockInQuestion); - - if ( - (BlockInQuestion == E_BLOCK_GLASS) || - (BlockInQuestion == E_BLOCK_STAINED_GLASS) || - (BlockInQuestion == E_BLOCK_FENCE) || - (BlockInQuestion == E_BLOCK_SOULSAND) || - (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || - (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour - (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || - (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) || - (BlockInQuestion == E_BLOCK_STONE_SLAB) || - (BlockInQuestion == E_BLOCK_WOODEN_SLAB) - ) - { - // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' - // No need to check for upright orientation, it was done when the torch was placed - return true; - } - else if (!cBlockInfo::FullyOccupiesVoxel(BlockInQuestion)) + NIBBLETYPE BlockInQuestionMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockInQuestion, BlockInQuestionMeta)) { return false; } - else - { - return true; - } + + return CanBePlacedOn(BlockInQuestion, BlockInQuestionMeta, Face); } -- cgit v1.2.3 From 9e4a5f824ae88e3a19de6a14db91b43c1759e29e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 30 Sep 2014 22:20:21 +0100 Subject: Removed WSSCompact --- src/BlockEntities/BeaconEntity.cpp | 62 -- src/BlockEntities/BeaconEntity.h | 2 - src/BlockEntities/BlockEntity.h | 2 - src/BlockEntities/ChestEntity.cpp | 42 -- src/BlockEntities/ChestEntity.h | 3 - src/BlockEntities/CommandBlockEntity.cpp | 32 - src/BlockEntities/CommandBlockEntity.h | 3 - src/BlockEntities/DropSpenserEntity.cpp | 48 -- src/BlockEntities/DropSpenserEntity.h | 3 - src/BlockEntities/EnderChestEntity.h | 1 - src/BlockEntities/FlowerPotEntity.cpp | 31 - src/BlockEntities/FlowerPotEntity.h | 3 - src/BlockEntities/FurnaceEntity.cpp | 54 -- src/BlockEntities/FurnaceEntity.h | 3 - src/BlockEntities/HopperEntity.cpp | 11 - src/BlockEntities/HopperEntity.h | 1 - src/BlockEntities/JukeboxEntity.cpp | 28 - src/BlockEntities/JukeboxEntity.h | 3 - src/BlockEntities/MobHeadEntity.cpp | 32 - src/BlockEntities/MobHeadEntity.h | 3 - src/BlockEntities/NoteEntity.cpp | 29 - src/BlockEntities/NoteEntity.h | 3 - src/BlockEntities/SignEntity.cpp | 35 - src/BlockEntities/SignEntity.h | 3 - src/WorldStorage/CMakeLists.txt | 2 - src/WorldStorage/WSSCompact.cpp | 1066 ------------------------------ src/WorldStorage/WSSCompact.h | 157 ----- src/WorldStorage/WorldStorage.cpp | 2 - 28 files changed, 1664 deletions(-) delete mode 100644 src/WorldStorage/WSSCompact.cpp delete mode 100644 src/WorldStorage/WSSCompact.h (limited to 'src') diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index dcf659f47..02f45a097 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -303,68 +303,6 @@ void cBeaconEntity::UsedBy(cPlayer * a_Player) -bool cBeaconEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - - m_BeaconLevel = (char)a_Value.get("Level", 0).asInt(); - int PrimaryEffect = a_Value.get("PrimaryEffect", 0).asInt(); - int SecondaryEffect = a_Value.get("SecondaryEffect", 0).asInt(); - - if ((PrimaryEffect >= 0) && (PrimaryEffect <= (int)cEntityEffect::effSaturation)) - { - m_PrimaryEffect = (cEntityEffect::eType)PrimaryEffect; - } - - if ((SecondaryEffect >= 0) && (SecondaryEffect <= (int)cEntityEffect::effSaturation)) - { - m_SecondaryEffect = (cEntityEffect::eType)SecondaryEffect; - } - - return true; -} - - - - - -void cBeaconEntity::SaveToJson(Json::Value& a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; - - a_Value["Level"] = m_BeaconLevel; - a_Value["PrimaryEffect"] = (int)m_PrimaryEffect; - a_Value["SecondaryEffect"] = (int)m_SecondaryEffect; -} - - - - - void cBeaconEntity::SendTo(cClientHandle & a_Client) { a_Client.SendUpdateBlockEntity(*this); diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 0d7150aef..8c2dad254 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -34,9 +34,7 @@ public: cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value& a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 066bbc696..54ab40f3e 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -74,8 +74,6 @@ public: int GetRelZ(void) const { return m_RelZ; } // tolua_end - - virtual void SaveToJson (Json::Value & a_Value) = 0; /// Called when a player uses this entity; should open the UI window virtual void UsedBy( cPlayer * a_Player) = 0; diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index a89e5747e..19d88b646 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -33,48 +33,6 @@ cChestEntity::~cChestEntity() -bool cChestEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - return true; -} - - - - - -void cChestEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; -} - - - - - void cChestEntity::SendTo(cClientHandle & a_Client) { // The chest entity doesn't need anything sent to the client when it's created / gets in the viewdistance diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index fa36e08be..af5d851a8 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -39,11 +39,8 @@ public: virtual ~cChestEntity(); static const char * GetClassStatic(void) { return "cChestEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 318874a9b..1a5a3f01e 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -152,38 +152,6 @@ void cCommandBlockEntity::SendTo(cClientHandle & a_Client) -bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Command = a_Value.get("Command", "").asString(); - m_LastOutput = a_Value.get("LastOutput", "").asString(); - m_Result = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt(); - - return true; -} - - - - - -void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Command"] = m_Command; - a_Value["LastOutput"] = m_LastOutput; - a_Value["SuccessCount"] = m_Result; -} - - - - - void cCommandBlockEntity::Execute() { ASSERT(m_World != NULL); // Execute should not be called before the command block is attached to a world diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 22cd44322..939f38610 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -39,9 +39,6 @@ public: /// Creates a new empty command block entity cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 05c7403e7..dac951b27 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -142,54 +142,6 @@ bool cDropSpenserEntity::Tick(float a_Dt, cChunk & a_Chunk) -bool cDropSpenserEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Contents; - Contents.FromJson(*itr); - m_Contents.SetSlot(SlotIdx, Contents); - SlotIdx++; - if (SlotIdx >= m_Contents.GetNumSlots()) - { - return true; - } - } - - return true; -} - - - - - -void cDropSpenserEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; -} - - - - - void cDropSpenserEntity::SendTo(cClientHandle & a_Client) { // Nothing needs to be sent diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index c70cd0531..23f0ae89a 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -49,11 +49,8 @@ public: virtual ~cDropSpenserEntity(); static const char * GetClassStatic(void) { return "cDropSpenserEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index 311af8d76..2719eb5e4 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -25,7 +25,6 @@ public: // cBlockEntity overrides: virtual void UsedBy(cPlayer * a_Player) override; - virtual void SaveToJson(Json::Value & a_Value) override { UNUSED(a_Value); } virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); } static void LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid); diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index d2bc59d34..01560f814 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -72,37 +72,6 @@ void cFlowerPotEntity::Destroy(void) -bool cFlowerPotEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Item = cItem(); - m_Item.FromJson(a_Value.get("Item", 0)); - - return true; -} - - - - - -void cFlowerPotEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value Item; - m_Item.GetJson(Item); - a_Value["Item"] = Item; -} - - - - - bool cFlowerPotEntity::IsFlower(short m_ItemType, short m_ItemData) { switch (m_ItemType) diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index b86f9c840..b68d3b118 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -38,9 +38,6 @@ public: /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); - - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; virtual void Destroy(void) override; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index fb88e9b35..4452fc00a 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -129,60 +129,6 @@ bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk) -bool cFurnaceEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - - m_NeedCookTime = (int)(a_Value.get("CookTime", 0).asDouble() / 50); - m_TimeCooked = (int)(a_Value.get("TimeCooked", 0).asDouble() / 50); - m_FuelBurnTime = (int)(a_Value.get("BurnTime", 0).asDouble() / 50); - m_TimeBurned = (int)(a_Value.get("TimeBurned", 0).asDouble() / 50); - - return true; -} - - - - - -void cFurnaceEntity::SaveToJson( Json::Value& a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; - - a_Value["CookTime"] = m_NeedCookTime * 50; - a_Value["TimeCooked"] = m_TimeCooked * 50; - a_Value["BurnTime"] = m_FuelBurnTime * 50; - a_Value["TimeBurned"] = m_TimeBurned * 50; -} - - - - - void cFurnaceEntity::SendTo(cClientHandle & a_Client) { // Nothing needs to be sent diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 7ac25cf52..ed3317af6 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -44,11 +44,8 @@ public: virtual ~cFurnaceEntity(); static const char * GetClassStatic() { return "cFurnaceEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 444378c92..103f516fc 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -70,17 +70,6 @@ bool cHopperEntity::Tick(float a_Dt, cChunk & a_Chunk) -void cHopperEntity::SaveToJson(Json::Value & a_Value) -{ - UNUSED(a_Value); - // TODO - LOGWARNING("%s: Not implemented yet", __FUNCTION__); -} - - - - - void cHopperEntity::SendTo(cClientHandle & a_Client) { // The hopper entity doesn't need anything sent to the client when it's created / gets in the viewdistance diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 8e856fcda..5d06581c2 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -49,7 +49,6 @@ protected: // cBlockEntity overrides: virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp index 1131b99b0..bb9b335e0 100644 --- a/src/BlockEntities/JukeboxEntity.cpp +++ b/src/BlockEntities/JukeboxEntity.cpp @@ -117,31 +117,3 @@ void cJukeboxEntity::SetRecord(int a_Record) - -bool cJukeboxEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Record = a_Value.get("Record", 0).asInt(); - - return true; -} - - - - - -void cJukeboxEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Record"] = m_Record; -} - - - - diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index a6fdf3c7e..49d2faa89 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -29,9 +29,6 @@ public: cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cJukeboxEntity(); - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; - // tolua_begin int GetRecord(void); diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp index 9a1a40abe..67e13ffb2 100644 --- a/src/BlockEntities/MobHeadEntity.cpp +++ b/src/BlockEntities/MobHeadEntity.cpp @@ -77,35 +77,3 @@ void cMobHeadEntity::SendTo(cClientHandle & a_Client) - -bool cMobHeadEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Type = static_cast(a_Value.get("Type", 0).asInt()); - m_Rotation = static_cast(a_Value.get("Rotation", 0).asInt()); - m_Owner = a_Value.get("Owner", "").asString(); - - return true; -} - - - - - -void cMobHeadEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Type"] = m_Type; - a_Value["Rotation"] = m_Rotation; - a_Value["Owner"] = m_Owner; -} - - - - diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 45fa0d951..fcdeaa8a6 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -37,9 +37,6 @@ public: /** Creates a new mob head entity at the specified block coords. a_World may be NULL */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - // tolua_begin /** Set the Type */ diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp index ecbedbcb1..a9af13c55 100644 --- a/src/BlockEntities/NoteEntity.cpp +++ b/src/BlockEntities/NoteEntity.cpp @@ -124,32 +124,3 @@ void cNoteEntity::IncrementPitch(void) - -bool cNoteEntity::LoadFromJson(const Json::Value & a_Value) -{ - - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Pitch = (char)a_Value.get("p", 0).asInt(); - - return true; -} - - - - - -void cNoteEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["p"] = m_Pitch; -} - - - - diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index f538de060..d1ffa126a 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -44,9 +44,6 @@ public: cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); virtual ~cNoteEntity() {} - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; - // tolua_begin char GetPitch(void); diff --git a/src/BlockEntities/SignEntity.cpp b/src/BlockEntities/SignEntity.cpp index 423d254d2..d048d0218 100644 --- a/src/BlockEntities/SignEntity.cpp +++ b/src/BlockEntities/SignEntity.cpp @@ -22,7 +22,6 @@ cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorl -// It don't do anything when 'used' void cSignEntity::UsedBy(cPlayer * a_Player) { UNUSED(a_Player); @@ -80,37 +79,3 @@ void cSignEntity::SendTo(cClientHandle & a_Client) - -bool cSignEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Line[0] = a_Value.get("Line1", "").asString(); - m_Line[1] = a_Value.get("Line2", "").asString(); - m_Line[2] = a_Value.get("Line3", "").asString(); - m_Line[3] = a_Value.get("Line4", "").asString(); - - return true; -} - - - - - -void cSignEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Line1"] = m_Line[0]; - a_Value["Line2"] = m_Line[1]; - a_Value["Line3"] = m_Line[2]; - a_Value["Line4"] = m_Line[3]; -} - - - - diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 33af100a4..53c43b758 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -37,9 +37,6 @@ public: /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - // tolua_begin /// Sets all the sign's lines diff --git a/src/WorldStorage/CMakeLists.txt b/src/WorldStorage/CMakeLists.txt index a00ff3b2f..59193db2a 100644 --- a/src/WorldStorage/CMakeLists.txt +++ b/src/WorldStorage/CMakeLists.txt @@ -14,7 +14,6 @@ SET (SRCS ScoreboardSerializer.cpp StatSerializer.cpp WSSAnvil.cpp - WSSCompact.cpp WorldStorage.cpp) SET (HDRS @@ -27,7 +26,6 @@ SET (HDRS ScoreboardSerializer.h StatSerializer.h WSSAnvil.h - WSSCompact.h WorldStorage.h) if(NOT MSVC) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp deleted file mode 100644 index 6760186b2..000000000 --- a/src/WorldStorage/WSSCompact.cpp +++ /dev/null @@ -1,1066 +0,0 @@ - -// WSSCompact.cpp - -// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files) - -#include "Globals.h" -#include "WSSCompact.h" -#include "../World.h" -#include "zlib/zlib.h" -#include "json/json.h" -#include "../StringCompression.h" -#include "../BlockEntities/BeaconEntity.h" -#include "../BlockEntities/ChestEntity.h" -#include "../BlockEntities/CommandBlockEntity.h" -#include "../BlockEntities/DispenserEntity.h" -#include "../BlockEntities/FlowerPotEntity.h" -#include "../BlockEntities/FurnaceEntity.h" -#include "../BlockEntities/JukeboxEntity.h" -#include "../BlockEntities/MobHeadEntity.h" -#include "../BlockEntities/NoteEntity.h" -#include "../BlockEntities/SignEntity.h" -#include "../SetChunkData.h" - - - - - -#pragma pack(push, 1) -/// The chunk header, as stored in the file: -struct cWSSCompact::sChunkHeader -{ - int m_ChunkX; - int m_ChunkZ; - int m_CompressedSize; - int m_UncompressedSize; -} ; -#pragma pack(pop) - - - - - -/// The maximum number of PAK files that are cached -const size_t MAX_PAK_FILES = 16; - -/// The maximum number of unsaved chunks before the cPAKFile saves them to disk -const int MAX_DIRTY_CHUNKS = 16; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cJsonChunkSerializer: - -cJsonChunkSerializer::cJsonChunkSerializer(void) : - m_HasJsonData(false) -{ -} - - - - - -void cJsonChunkSerializer::Entity(cEntity * a_Entity) -{ - // TODO: a_Entity->SaveToJson(m_Root); -} - - - - - -void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) -{ - const char * SaveInto = NULL; - switch (a_BlockEntity->GetBlockType()) - { - case E_BLOCK_BEACON: SaveInto = "Beacons"; break; - case E_BLOCK_CHEST: SaveInto = "Chests"; break; - case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; break; - case E_BLOCK_DROPPER: SaveInto = "Droppers"; break; - case E_BLOCK_FLOWER_POT: SaveInto = "FlowerPots"; break; - case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; - case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; - case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; - case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break; - case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break; - case E_BLOCK_COMMAND_BLOCK: SaveInto = "CommandBlocks"; break; - case E_BLOCK_HEAD: SaveInto = "MobHeads"; break; - - default: - { - ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); - break; - } - } // switch (BlockEntity->GetBlockType()) - if (SaveInto == NULL) - { - return; - } - - Json::Value val; - a_BlockEntity->SaveToJson(val); - m_Root[SaveInto].append(val); - m_HasJsonData = true; -} - - - - - -void cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) -{ - if (a_IsLightValid) - { - m_Root["IsLightValid"] = true; - m_HasJsonData = true; - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWSSCompact: - -cWSSCompact::~cWSSCompact() -{ - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk) -{ - AString ChunkData; - int UncompressedSize = 0; - if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData)) - { - // The reason for failure is already printed in GetChunkData() - return false; - } - - return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World); -} - - - - - -bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - // For some reason we couldn't locate the file - LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - return f->SaveChunk(a_Chunk, m_World); -} - - - - - -cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) -{ - // ASSUMES that m_CS has been locked - - // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file - const int LayerX = FAST_FLOOR_DIV(a_Chunk.m_ChunkX, 32); - const int LayerZ = FAST_FLOOR_DIV(a_Chunk.m_ChunkZ, 32); - - // Is it already cached? - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ)) - { - // Move the file to front and return it: - cPAKFile * f = *itr; - if (itr != m_PAKFiles.begin()) - { - m_PAKFiles.erase(itr); - m_PAKFiles.push_front(f); - } - return f; - } - } - - // Load it anew: - AString FileName; - Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ); - cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ, m_CompressionFactor); - if (f == NULL) - { - return NULL; - } - m_PAKFiles.push_front(f); - - // If there are too many PAK files cached, delete the last one used: - if (m_PAKFiles.size() > MAX_PAK_FILES) - { - delete m_PAKFiles.back(); - m_PAKFiles.pop_back(); - } - return f; -} - - - - - -bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} - - - - - -/* -// TODO: Rewrite saving to use the same principles as loading -bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} -*/ - - - - - -bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->EraseChunkData(a_Chunk); -} - - - - - -void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) -{ - // Load beacon: - Json::Value AllBeacons = a_Value.get("Beacons", Json::nullValue); - if (!AllBeacons.empty()) - { - for (Json::Value::iterator itr = AllBeacons.begin(); itr != AllBeacons.end(); ++itr) - { - std::auto_ptr BeaconEntity(new cBeaconEntity(0, 0, 0, a_World)); - if (!BeaconEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING BEACON FROM JSON!"); - } - else - { - a_BlockEntities.push_back(BeaconEntity.release()); - } - } // for itr - AllBeacons[] - } - - // Load chests: - Json::Value AllChests = a_Value.get("Chests", Json::nullValue); - if (!AllChests.empty()) - { - for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr) - { - std::auto_ptr ChestEntity(new cChestEntity(0, 0, 0, a_World, E_BLOCK_CHEST)); - if (!ChestEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING CHEST FROM JSON!"); - } - else - { - a_BlockEntities.push_back(ChestEntity.release()); - } - } // for itr - AllChests[] - } - - // Load dispensers: - Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue); - for (Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr) - { - std::auto_ptr DispenserEntity(new cDispenserEntity(0, 0, 0, a_World)); - if (!DispenserEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING DISPENSER FROM JSON!"); - } - else - { - a_BlockEntities.push_back(DispenserEntity.release()); - } - } // for itr - AllDispensers[] - - // Load Flowerpots: - Json::Value AllFlowerPots = a_Value.get("FlowerPots", Json::nullValue); - for (Json::Value::iterator itr = AllFlowerPots.begin(); itr != AllFlowerPots.end(); ++itr) - { - std::auto_ptr FlowerPotEntity(new cFlowerPotEntity(0, 0, 0, a_World)); - if (!FlowerPotEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING FLOWERPOT FROM JSON!"); - } - else - { - a_BlockEntities.push_back(FlowerPotEntity.release()); - } - } // for itr - AllFlowerPots[] - - // Load furnaces: - Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); - for (Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr) - { - // TODO: The block type and meta aren't correct, there's no way to get them here - std::auto_ptr FurnaceEntity(new cFurnaceEntity(0, 0, 0, E_BLOCK_FURNACE, 0, a_World)); - if (!FurnaceEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING FURNACE FROM JSON!"); - } - else - { - a_BlockEntities.push_back(FurnaceEntity.release()); - } - } // for itr - AllFurnaces[] - - // Load signs: - Json::Value AllSigns = a_Value.get("Signs", Json::nullValue); - for (Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr) - { - std::auto_ptr SignEntity(new cSignEntity(E_BLOCK_SIGN_POST, 0, 0, 0, a_World)); - if (!SignEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING SIGN FROM JSON!"); - } - else - { - a_BlockEntities.push_back(SignEntity.release()); - } - } // for itr - AllSigns[] - - // Load note blocks: - Json::Value AllNotes = a_Value.get("Notes", Json::nullValue); - for (Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr) - { - std::auto_ptr NoteEntity(new cNoteEntity(0, 0, 0, a_World)); - if (!NoteEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING NOTE BLOCK FROM JSON!"); - } - else - { - a_BlockEntities.push_back(NoteEntity.release()); - } - } // for itr - AllNotes[] - - // Load jukeboxes: - Json::Value AllJukeboxes = a_Value.get("Jukeboxes", Json::nullValue); - for (Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr) - { - std::auto_ptr JukeboxEntity(new cJukeboxEntity(0, 0, 0, a_World)); - if (!JukeboxEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING JUKEBOX FROM JSON!"); - } - else - { - a_BlockEntities.push_back(JukeboxEntity.release()); - } - } // for itr - AllJukeboxes[] - - // Load command blocks: - Json::Value AllCommandBlocks = a_Value.get("CommandBlocks", Json::nullValue); - for (Json::Value::iterator itr = AllCommandBlocks.begin(); itr != AllCommandBlocks.end(); ++itr) - { - std::auto_ptr CommandBlockEntity(new cCommandBlockEntity(0, 0, 0, a_World)); - if (!CommandBlockEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING COMMAND BLOCK FROM JSON!"); - } - else - { - a_BlockEntities.push_back(CommandBlockEntity.release()); - } - } // for itr - AllCommandBlocks[] - - // Load mob heads: - Json::Value AllMobHeads = a_Value.get("MobHeads", Json::nullValue); - for (Json::Value::iterator itr = AllMobHeads.begin(); itr != AllMobHeads.end(); ++itr) - { - std::auto_ptr MobHeadEntity(new cMobHeadEntity(0, 0, 0, a_World)); - if (!MobHeadEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING MOB HEAD FROM JSON!"); - } - else - { - a_BlockEntities.push_back(MobHeadEntity.release()); - } - } // for itr - AllMobHeads[] -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWSSCompact::cPAKFile - -#define READ(Var) \ - if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ, int a_CompressionFactor) : - m_FileName(a_FileName), - m_CompressionFactor(a_CompressionFactor), - m_LayerX(a_LayerX), - m_LayerZ(a_LayerZ), - m_NumDirty(0), - m_ChunkVersion( CHUNK_VERSION), // Init with latest version - m_PakVersion( PAK_VERSION) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmRead)) - { - return; - } - - // Read headers: - READ(m_PakVersion); - if (m_PakVersion != 1) - { - LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion); - return; - } - - READ(m_ChunkVersion); - switch (m_ChunkVersion) - { - case 1: - { - m_ChunkSize.Set(16, 128, 16); - break; - } - case 2: - case 3: - { - m_ChunkSize.Set(16, 256, 16); - break; - } - default: - { - LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion); - return; - } - }; - - short NumChunks = 0; - READ(NumChunks); - - // Read chunk headers: - for (int i = 0; i < NumChunks; i++) - { - sChunkHeader * Header = new sChunkHeader; - - // Here we do not use the READ macro, as it does not free the resources - // allocated with new in case of error. - if (f.Read(Header, sizeof(*Header)) != sizeof(*Header)) - { - LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell()); - delete Header; - Header = NULL; - return; - } - m_ChunkHeaders.push_back(Header); - } // for i - chunk headers - - // Read chunk data: - if (f.ReadRestOfFile(m_DataContents) == -1) - { - LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str()); - return; - } - - if (m_ChunkVersion == 1) // Convert chunks to version 2 - { - UpdateChunk1To2(); - } -#if AXIS_ORDER == AXIS_ORDER_XZY - if (m_ChunkVersion == 2) // Convert chunks to version 3 - { - UpdateChunk2To3(); - } -#endif -} - - - - - -cWSSCompact::cPAKFile::~cPAKFile() -{ - if (m_NumDirty > 0) - { - SynchronizeFile(); - } - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - sChunkHeader * Header = NULL; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - Header = *itr; - break; - } - Offset += (*itr)->m_CompressedSize; - } - if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size())) - { - // Chunk not found / data invalid - return false; - } - - a_UncompressedSize = Header->m_UncompressedSize; - a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - return true; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - if (!SaveChunkToData(a_Chunk, a_World)) - { - return false; - } - if (m_NumDirty > MAX_DIRTY_CHUNKS) - { - SynchronizeFile(); - } - return true; -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk1To2() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if (ChunksConverted % 32 == 0) - { - LOGINFO("Updating \"%s\" version 1 to version 2: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size()); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - - // Old version is 128 blocks high with YZX axis order - char ConvertedData[cChunkDef::BlockDataSize]; - int Index = 0; - unsigned int InChunkOffset = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) - { - for (int y = 0; y < 128; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset]; - } - // Add 128 empty blocks after an old y column - memset(ConvertedData + Index, E_BLOCK_AIR, 128); - Index += 128; - } - InChunkOffset += (16 * 128 * 16); - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Metadata - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Block light - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16*128*16)/2; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Sky light - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - - AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData)); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end()); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = (int)Converted.size(); - Header->m_CompressedSize = (int)CompressedData.size(); - NewDataContents.append(CompressedData); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 2; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str()); -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk2To3() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if (ChunksConverted % 32 == 0) - { - LOGINFO("Updating \"%s\" version 2 to version 3: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size()); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - const int ExpectedSize = (16 * 256 * 16) * 2 + (16 * 256 * 16) / 2; // For version 2 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - char ConvertedData[ExpectedSize]; - memset(ConvertedData, 0, ExpectedSize); - - // Cannot use cChunk::MakeIndex because it might change again????????? - // For compatibility, use what we know is current - #define MAKE_3_INDEX( x, y, z) ( x + (z * 16) + (y * 16 * 16)) - - unsigned int InChunkOffset = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) // YZX Loop order is important, in 1.1 Y was first then Z then X - { - ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset]; - ++InChunkOffset; - } // for y, z, x - - - unsigned int index2 = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - - AString Converted(ConvertedData, ExpectedSize); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end()); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = (int)Converted.size(); - Header->m_CompressedSize = (int)CompressedData.size(); - NewDataContents.append(CompressedData); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 3; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str()); -} - - - - - -bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World) -{ - // Crude data integrity check: - if (a_UncompressedSize < cChunkDef::BlockDataSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - a_UncompressedSize, cChunkDef::BlockDataSize - ); - EraseChunkData(a_Chunk); - return false; - } - - // Decompress the data: - AString UncompressedData; - int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, (size_t)a_UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - if (a_UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - a_UncompressedSize, UncompressedData.size(), - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - cEntityList Entities; - cBlockEntityList BlockEntities; - bool IsLightValid = false; - - if (a_UncompressedSize > cChunkDef::BlockDataSize) - { - Json::Value root; // will contain the root value after parsing. - Json::Reader reader; - if (!reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false)) - { - LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - } - else - { - LoadEntitiesFromJson(root, Entities, BlockEntities, a_World); - IsLightValid = root.get("IsLightValid", false).asBool(); - } - } - - BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data(); - NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + MetaOffset); - NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + LightOffset); - NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + SkyLightOffset); - - a_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - BlockData, MetaData, - IsLightValid ? BlockLight : NULL, - IsLightValid ? SkyLight : NULL, - NULL, NULL, - Entities, BlockEntities, - false - ))); - - return true; -} - - - - - -bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - m_DataContents.erase(Offset, (*itr)->m_CompressedSize); - delete *itr; - itr = m_ChunkHeaders.erase(itr); - return true; - } - Offset += (*itr)->m_CompressedSize; - } - - return false; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - // Serialize the chunk: - cJsonChunkSerializer Serializer; - if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) - { - // Chunk not valid - LOG("cWSSCompact: Trying to save chunk [%d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - - AString Data; - Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); - if (Serializer.HasJsonData()) - { - AString JsonData; - Json::StyledWriter writer; - JsonData = writer.write(Serializer.GetRoot()); - Data.append(JsonData); - } - - // Compress the data: - AString CompressedData; - int errorcode = CompressString(Data.data(), Data.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %i compressing data for chunk [%d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - - // Erase any existing data for the chunk: - EraseChunkData(a_Chunk); - - // Save the header: - sChunkHeader * Header = new sChunkHeader; - if (Header == NULL) - { - LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - Header->m_CompressedSize = (int)CompressedData.size(); - Header->m_ChunkX = a_Chunk.m_ChunkX; - Header->m_ChunkZ = a_Chunk.m_ChunkZ; - Header->m_UncompressedSize = (int)Data.size(); - m_ChunkHeaders.push_back(Header); - - m_DataContents.append(CompressedData.data(), CompressedData.size()); - - m_NumDirty++; - return true; -} - - - - - -#define WRITE(Var) \ - if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -void cWSSCompact::cPAKFile::SynchronizeFile(void) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmWrite)) - { - LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str()); - return; - } - - WRITE(m_PakVersion); - WRITE(m_ChunkVersion); - short NumChunks = (short)m_ChunkHeaders.size(); - WRITE(NumChunks); - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - WRITE(**itr); - } - if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size()) - { - LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell()); - return; - } - m_NumDirty = 0; -} - - - - diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h deleted file mode 100644 index 83e9cb49f..000000000 --- a/src/WorldStorage/WSSCompact.h +++ /dev/null @@ -1,157 +0,0 @@ - -// WSSCompact.h - -// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files) - - - - - -#pragma once -#ifndef WSSCOMPACT_H_INCLUDED -#define WSSCOMPACT_H_INCLUDED - -#include "WorldStorage.h" -#include "../Vector3.h" -#include "json/json.h" -#include "ChunkDataCallback.h" - - - - - -/// Helper class for serializing a chunk into Json -class cJsonChunkSerializer : - public cChunkDataArrayCollector -{ -public: - - cJsonChunkSerializer(void); - - Json::Value & GetRoot (void) {return m_Root; } - BLOCKTYPE * GetBlockData(void) {return (BLOCKTYPE *)m_BlockData; } - bool HasJsonData (void) const {return m_HasJsonData; } - -protected: - - // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array - - // Entities and BlockEntities are serialized to Json - Json::Value m_Root; - bool m_HasJsonData; - - // cChunkDataCollector overrides: - virtual void Entity (cEntity * a_Entity) override; - virtual void BlockEntity (cBlockEntity * a_Entity) override; - virtual void LightIsValid (bool a_IsLightValid) override; -} ; - - - - - -class cWSSCompact : - public cWSSchema -{ -public: - cWSSCompact(cWorld * a_World, int a_CompressionFactor) : cWSSchema(a_World), m_CompressionFactor(a_CompressionFactor) {} - virtual ~cWSSCompact(); - -protected: - - enum - { - // Offsets to individual components in the joined blockdata array - MetaOffset = cChunkDef::NumBlocks, - LightOffset = MetaOffset + cChunkDef::NumBlocks / 2, - SkyLightOffset = LightOffset + cChunkDef::NumBlocks / 2, - } ; - - struct sChunkHeader; - typedef std::vector sChunkHeaders; - - /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast - class cPAKFile - { - public: - - cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ, int a_CompressionFactor); - ~cPAKFile(); - - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - bool EraseChunkData(const cChunkCoords & a_Chunk); - - bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World); - - int GetLayerX(void) const {return m_LayerX; } - int GetLayerZ(void) const {return m_LayerZ; } - - static const int PAK_VERSION = 1; -#if AXIS_ORDER == AXIS_ORDER_XZY - static const int CHUNK_VERSION = 3; -#elif AXIS_ORDER == AXIS_ORDER_YZX - static const int CHUNK_VERSION = 2; -#endif - protected: - - AString m_FileName; - int m_CompressionFactor; - int m_LayerX; - int m_LayerZ; - - sChunkHeaders m_ChunkHeaders; - AString m_DataContents; // Data contents of the file, cached - - int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file - - Vector3i m_ChunkSize; // Is related to m_ChunkVersion - char m_ChunkVersion; - char m_PakVersion; - - bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty - void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty - - void UpdateChunk1To2(void); // Height from 128 to 256 - void UpdateChunk2To3(void); // Axis order from YZX to XZY - } ; - - typedef std::list cPAKFiles; - - cCriticalSection m_CS; - cPAKFiles m_PAKFiles; // A MRU cache of PAK files - - int m_CompressionFactor; - - /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache - cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk); - - /// Gets chunk data from the correct file; locks CS as needed - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - - /// Sets chunk data to the correct file; locks CS as needed - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - - /// Erases chunk data from the correct file; locks CS as needed - bool EraseChunkData(const cChunkCoords & a_Chunk); - - /// Loads the chunk from the data (no locking needed) - bool LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World); - - void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World); - - // cWSSchema overrides: - virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; - virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; - virtual const AString GetName(void) const override {return "compact"; } -} ; - - - - - -#endif // WSSCOMPACT_H_INCLUDED - - - - diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 179cf9393..c611bfd90 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -7,7 +7,6 @@ #include "Globals.h" #include "WorldStorage.h" -#include "WSSCompact.h" #include "WSSAnvil.h" #include "../World.h" #include "../Generating/ChunkGenerator.h" @@ -187,7 +186,6 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) { // The first schema added is considered the default m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor)); - m_Schemas.push_back(new cWSSCompact (m_World, a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSForgetful(m_World)); // Add new schemas here -- cgit v1.2.3 From e65e0f1795e170dc339d5062eb2322e4c673560d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 1 Oct 2014 12:14:38 +0200 Subject: cClientHandle: Alpha-sorted the sending functions. --- src/ClientHandle.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 1f22762c0..20592c190 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -145,7 +145,9 @@ public: void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player); void SendDestroyEntity (const cEntity & a_Entity); void SendDisconnect (const AString & a_Reason); + void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); + void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration); void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); void SendEntityHeadLook (const cEntity & a_Entity); @@ -156,6 +158,8 @@ public: void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityStatus (const cEntity & a_Entity, char a_Status); void SendEntityVelocity (const cEntity & a_Entity); + void SendExperience (void); + void SendExperienceOrb (const cExpOrb & a_ExpOrb); void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion); void SendGameMode (eGameMode a_GameMode); void SendHealth (void); @@ -164,15 +168,14 @@ public: void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale); void SendMapInfo (int a_ID, unsigned int a_Scale); void SendPaintingSpawn (const cPainting & a_Painting); - void SendPickupSpawn (const cPickup & a_Pickup); - void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); + void SendPickupSpawn (const cPickup & a_Pickup); void SendPlayerAbilities (void); void SendPlayerListAddPlayer (const cPlayer & a_Player); void SendPlayerListRemovePlayer (const cPlayer & a_Player); + void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName); void SendPlayerListUpdateGameMode (const cPlayer & a_Player); void SendPlayerListUpdatePing (const cPlayer & a_Player); - void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); @@ -180,11 +183,8 @@ public: void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false); - void SendExperience (void); - void SendExperienceOrb (const cExpOrb & a_ExpOrb); - void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); - void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); + void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); -- cgit v1.2.3 From 901bed39895be35ceb66352f8120b8117f44fb4e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 1 Oct 2014 12:44:28 +0200 Subject: Unified cRoot broadcast chat documentation. --- src/Root.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Root.h b/src/Root.h index 9a482556c..23ed81989 100644 --- a/src/Root.h +++ b/src/Root.h @@ -129,15 +129,15 @@ public: /// Sends a chat message to all connected clients (in all worlds) void BroadcastChat (const AString & a_Message, eMessageType a_ChatPrefix = mtCustom); - void BroadcastChatInfo (const AString & a_Message) { BroadcastChat(a_Message, mtInformation); } + void BroadcastChat (const cCompositeChat & a_Message); + void BroadcastChatDeath (const AString & a_Message) { BroadcastChat(a_Message, mtDeath); } void BroadcastChatFailure(const AString & a_Message) { BroadcastChat(a_Message, mtFailure); } - void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(a_Message, mtSuccess); } - void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(a_Message, mtWarning); } void BroadcastChatFatal (const AString & a_Message) { BroadcastChat(a_Message, mtFailure); } + void BroadcastChatInfo (const AString & a_Message) { BroadcastChat(a_Message, mtInformation); } void BroadcastChatJoin (const AString & a_Message) { BroadcastChat(a_Message, mtJoin); } void BroadcastChatLeave (const AString & a_Message) { BroadcastChat(a_Message, mtLeave); } - void BroadcastChatDeath (const AString & a_Message) { BroadcastChat(a_Message, mtDeath); } - void BroadcastChat (const cCompositeChat & a_Message); + void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(a_Message, mtSuccess); } + void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(a_Message, mtWarning); } /// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum); -- cgit v1.2.3 From 886a7d7bbb48dbff2975892c441c68cfd5ad281b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 1 Oct 2014 12:59:31 +0200 Subject: Bindings: Fixed binding for cPlayer::PermissionMatches(). --- src/Bindings/ManualBindings.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index d8134f159..f4764447c 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1957,26 +1957,20 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) // Check the params: cLuaState L(tolua_S); if ( - !L.CheckParamUserType(1, "cPlayer") || - !L.CheckParamString (2, 3) || - !L.CheckParamEnd (4) + !L.CheckParamUserTable(1, "cPlayer") || + !L.CheckParamString (2, 3) || + !L.CheckParamEnd (4) ) { return 0; } // Get the params: - cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) - { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); - return 0; - } AString Permission, Template; L.GetStackValues(2, Permission, Template); // Push the result of the match: - L.Push(self->PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); + L.Push(cPlayer::PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); return 1; } -- cgit v1.2.3 From fd11b574bdc31721b007b31f1734f9ea69a2cd94 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 1 Oct 2014 17:24:02 +0200 Subject: cPlayer: Removed useless functions from the Lua API. --- src/Entities/Player.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index ffd0b7e03..22d6a2ae2 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -182,11 +182,11 @@ public: /** Sets the player team, NULL if none */ void SetTeam(cTeam * a_Team); + // tolua_end + /** Forces the player to query the scoreboard for his team */ cTeam * UpdateTeam(void); - // tolua_end - /** Return the associated statistic and achievement manager. */ cStatManager & GetStatManager() { return m_Stats; } @@ -421,9 +421,13 @@ public: /** Sets the player's bed (home) position */ void SetBedPos(const Vector3i & a_Pos) { m_LastBedPos = a_Pos; } + + // tolua_end /** Update movement-related statistics. */ void UpdateMovementStats(const Vector3d & a_DeltaPos); + + // tolua_begin /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } -- cgit v1.2.3 From 4789db5c28cca53078387711011f0d3901d6a364 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 1 Oct 2014 17:28:45 +0200 Subject: cRoot: Removed useless variable from Lua API. --- src/Root.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Root.h b/src/Root.h index 23ed81989..84c6a98ec 100644 --- a/src/Root.h +++ b/src/Root.h @@ -41,11 +41,12 @@ namespace Json class cRoot { public: - static bool m_TerminateEventRaised; - static cRoot * Get() { return s_Root; } // tolua_end + static bool m_TerminateEventRaised; + + cRoot(void); ~cRoot(); -- cgit v1.2.3 From cc9e5988039c760311f34fba721a1d3c20126097 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 1 Oct 2014 17:57:53 +0200 Subject: Added missing 1.8 blocks, E_METAs and sounds --- src/BlockID.h | 53 ++++++++++++++++++++++++++++++++++++++++++------ src/BlockInfo.cpp | 11 +++++++++- src/Blocks/BlockPiston.h | 2 ++ 3 files changed, 59 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 03a7f63e6..014b02fa8 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -186,6 +186,9 @@ enum ENUM_BLOCK_ID E_BLOCK_BLOCK_OF_COAL = 173, E_BLOCK_PACKED_ICE = 174, E_BLOCK_BIG_FLOWER = 175, + E_BLOCK_STANDING_BANNER = 176, + E_BLOCK_WALL_BANNER = 177, + E_BLOCK_INVERTED_DAYLIGHT_SENSOR = 178, E_BLOCK_RED_SANDSTONE = 179, E_BLOCK_RED_SANDSTONE_STAIRS = 180, E_BLOCK_DOUBLE_NEW_STONE_SLAB= 181, @@ -541,15 +544,22 @@ enum E_META_NEW_LOG_DARK_OAK_WOOD = 1, // E_BLOCK_PLANKS metas: - E_META_PLANKS_APPLE = 0, - E_META_PLANKS_CONIFER = 1, - E_META_PLANKS_BIRCH = 2, - E_META_PLANKS_JUNGLE = 3, + E_META_PLANKS_APPLE = 0, + E_META_PLANKS_CONIFER = 1, + E_META_PLANKS_BIRCH = 2, + E_META_PLANKS_JUNGLE = 3, + E_META_PLANKS_ACACIA = 4, + E_META_PLANKS_DARK_OAK = 5, // E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas: E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_DEPRESSED = 1, + // E_BLOCK_PRISMARINE + E_META_PRISMRAINE_ROUGH = 0, + E_META_PRISMARINE_BRICKS = 1, + E_META_PRISMARINE_DARK = 2, + // E_BLOCK_QUARTZ_BLOCK metas: E_META_QUARTZ_NORMAL = 0, E_META_QUARTZ_CHISELLED = 1, @@ -567,6 +577,11 @@ enum E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XP = 9, + // E_BLOCK_RED_SANDSTONE + E_META_RED_SANDSTONE_NORMAL = 0, + E_META_RED_SANDSTONE_ORNAMENT = 1, + E_META_RED_SANDSTONE_SMOOTH = 2, + // E_BLOCK_SAND metas: E_META_SAND_NORMAL = 0, E_META_SAND_RED = 1, @@ -656,8 +671,11 @@ enum // E_BLOCK_STONE metas: E_META_STONE = 0, E_META_STONE_GRANITE = 1, + E_META_STONE_POLISHED_GRANITE = 2, E_META_STONE_DIORITE = 3, + E_META_STONE_POLISHED_DIORITE = 4, E_META_STONE_ANDESITE = 5, + E_META_STONE_POLISHED_ANDESITE = 6, // E_BLOCK_STONE_SLAB metas: E_META_STONE_SLAB_STONE = 0, @@ -728,6 +746,24 @@ enum //////////////////////////////////////////////////////////////////////////////// // Item metas: + // E_ITEM_BANNER: + E_META_BANNER_BLACK = 0, + E_META_BANNER_RED = 1, + E_META_BANNER_GREEN = 2, + E_META_BANNER_BROWN = 3, + E_META_BANNER_BLUE = 4, + E_META_BANNER_PURPLE = 5, + E_META_BANNER_CYAN = 6, + E_META_BANNER_LIGHTGRAY = 7, + E_META_BANNER_GRAY = 8, + E_META_BANNER_PINK = 9, + E_META_BANNER_LIGHTGREEN = 10, + E_META_BANNER_YELLOW = 11, + E_META_BANNER_LIGHTBLUE = 12, + E_META_BANNER_MAGENTA = 13, + E_META_BANNER_ORANGE = 14, + E_META_BANNER_WHITE = 15, + // E_ITEM_COAL metas: E_META_COAL_NORMAL = 0, E_META_COAL_CHARCOAL = 1, @@ -754,6 +790,13 @@ enum E_META_GOLDEN_APPLE_NORMAL = 0, E_META_GOLDEN_APPLE_ENCHANTED = 1, + // E_ITEM_HEAD: + E_META_HEAD_SKELETON = 0, + E_META_HEAD_WITHER = 1, + E_META_HEAD_ZOMBIE = 2, + E_META_HEAD_PLAYER = 3, + E_META_HEAD_CREEPER = 4, + // E_ITEM_RAW_FISH metas: E_META_RAW_FISH_FISH = 0, E_META_RAW_FISH_SALMON = 1, @@ -763,8 +806,6 @@ enum // E_ITEM_COOKED_FISH metas: E_META_COOKED_FISH_FISH = 0, E_META_COOKED_FISH_SALMON = 1, - E_META_COOKED_FISH_CLOWNFISH = 2, - E_META_COOKED_FISH_PUFFERFISH = 3, // E_ITEM_MINECART_TRACKS metas: E_META_TRACKS_X = 1, diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 719ba0550..5e30514e2 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -99,6 +99,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_HOPPER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_ICE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_INVERTED_DAYLIGHT_SENSOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_SpreadLightFalloff = 1; @@ -137,6 +138,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_STANDING_BANNER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STICKY_PISTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STONE_BUTTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_SpreadLightFalloff = 1; @@ -149,6 +151,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_WALL_BANNER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_BUTTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; @@ -256,6 +259,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; + a_Info[E_BLOCK_STANDING_BANNER ].m_Transparent = true; a_Info[E_BLOCK_STICKY_PISTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; @@ -268,6 +272,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true; a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true; a_Info[E_BLOCK_VINES ].m_Transparent = true; + a_Info[E_BLOCK_WALL_BANNER ].m_Transparent = true; a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; a_Info[E_BLOCK_WATER ].m_Transparent = true; a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; @@ -475,12 +480,14 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SNOW ].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; + a_Info[E_BLOCK_STANDING_BANNER ].m_IsSolid = false; a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; a_Info[E_BLOCK_TORCH ].m_IsSolid = false; a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; a_Info[E_BLOCK_VINES ].m_IsSolid = false; + a_Info[E_BLOCK_WALL_BANNER ].m_IsSolid = false; a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; a_Info[E_BLOCK_WATER ].m_IsSolid = false; a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; @@ -735,7 +742,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; - a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // TODO: Check that this is the correct name + a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "mob.slime.big"; a_Info[E_BLOCK_BARRIER ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal"; a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone"; @@ -746,6 +753,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_STANDING_BANNER ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_WALL_BANNER ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_RED_SANDSTONE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_RED_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_NEW_STONE_SLAB ].m_PlaceSound = "dig.stone"; diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 3a3fc7224..05bc3d3f9 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -115,7 +115,9 @@ private: case E_BLOCK_NOTE_BLOCK: case E_BLOCK_OBSIDIAN: case E_BLOCK_PISTON_EXTENSION: + case E_BLOCK_STANDING_BANNER: case E_BLOCK_TRAPPED_CHEST: + case E_BLOCK_WALL_BANNER: { return false; } -- cgit v1.2.3 From 0f0763303e804e6447c5523a10c80ca2d5c844a0 Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 1 Oct 2014 18:00:51 +0200 Subject: Fixed ":" --- src/BlockID.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 014b02fa8..9787b3bfa 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -445,7 +445,7 @@ enum //////////////////////////////////////////////////////////////////////////////// // Block metas: - // E_BLOCK_BIG_FLOWER metas + // E_BLOCK_BIG_FLOWER metas: E_META_BIG_FLOWER_SUNFLOWER = 0, E_META_BIG_FLOWER_LILAC = 1, E_META_BIG_FLOWER_DOUBLE_TALL_GRASS = 2, @@ -501,7 +501,7 @@ enum E_META_DOUBLE_STONE_SLAB_NETHER_BRICK = 6, E_META_DOUBLE_STONE_SLAB_STONE_SECRET = 7, - // E_BLOCK_FLOWER metas + // E_BLOCK_FLOWER metas: E_META_FLOWER_POPPY = 0, E_META_FLOWER_BLUE_ORCHID = 1, E_META_FLOWER_ALLIUM = 2, @@ -511,7 +511,7 @@ enum E_META_FLOWER_PINK_TULIP = 7, E_META_FLOWER_OXEYE_DAISY = 8, - // E_BLOCK_JUKEBOX metas + // E_BLOCK_JUKEBOX metas: E_META_JUKEBOX_OFF = 0, E_META_JUKEBOX_ON = 1, @@ -535,11 +535,11 @@ enum E_META_LOG_BIRCH = 2, E_META_LOG_JUNGLE = 3, - // E_BLOCK_NEW_LEAVES metas + // E_BLOCK_NEW_LEAVES metas: E_META_NEW_LEAVES_ACACIA_WOOD = 0, E_META_NEW_LEAVES_DARK_OAK_WOOD = 1, - // E_BLOCK_NEW_LOG metas + // E_BLOCK_NEW_LOG metas: E_META_NEW_LOG_ACACIA_WOOD = 0, E_META_NEW_LOG_DARK_OAK_WOOD = 1, @@ -555,7 +555,7 @@ enum E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_DEPRESSED = 1, - // E_BLOCK_PRISMARINE + // E_BLOCK_PRISMARINE: E_META_PRISMRAINE_ROUGH = 0, E_META_PRISMARINE_BRICKS = 1, E_META_PRISMARINE_DARK = 2, @@ -565,7 +565,7 @@ enum E_META_QUARTZ_CHISELLED = 1, E_META_QUARTZ_PILLAR = 2, - // E_BLOCK_RAIL metas + // E_BLOCK_RAIL metas: E_META_RAIL_ZM_ZP = 0, E_META_RAIL_XM_XP = 1, E_META_RAIL_ASCEND_XP = 2, @@ -577,7 +577,7 @@ enum E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XP = 9, - // E_BLOCK_RED_SANDSTONE + // E_BLOCK_RED_SANDSTONE: E_META_RED_SANDSTONE_NORMAL = 0, E_META_RED_SANDSTONE_ORNAMENT = 1, E_META_RED_SANDSTONE_SMOOTH = 2, @@ -614,7 +614,7 @@ enum E_META_SNOW_LAYER_SEVEN = 6, E_META_SNOW_LAYER_EIGHT = 7, - // E_BLOCK_STAINED_CLAY metas + // E_BLOCK_STAINED_CLAY metas: E_META_STAINED_CLAY_WHITE = 0, E_META_STAINED_CLAY_ORANGE = 1, E_META_STAINED_CLAY_MAGENTA = 2, @@ -632,7 +632,7 @@ enum E_META_STAINED_CLAY_RED = 14, E_META_STAINED_CLAY_BLACK = 15, - // E_BLOCK_STAINED_GLASS metas + // E_BLOCK_STAINED_GLASS metas: E_META_STAINED_GLASS_WHITE = 0, E_META_STAINED_GLASS_ORANGE = 1, E_META_STAINED_GLASS_MAGENTA = 2, @@ -650,7 +650,7 @@ enum E_META_STAINED_GLASS_RED = 14, E_META_STAINED_GLASS_BLACK = 15, - // E_BLOCK_STAINED_GLASS_PANE metas + // E_BLOCK_STAINED_GLASS_PANE metas: E_META_STAINED_GLASS_PANE_WHITE = 0, E_META_STAINED_GLASS_PANE_ORANGE = 1, E_META_STAINED_GLASS_PANE_MAGENTA = 2, -- cgit v1.2.3 From 1d875d0bc8d1cf91baa20b592b19a1167cad978a Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 1 Oct 2014 18:08:31 +0200 Subject: Added Daylight Sensors to the "can't push" list --- src/Blocks/BlockPiston.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 05bc3d3f9..f868f4d8e 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -100,6 +100,7 @@ private: case E_BLOCK_BREWING_STAND: case E_BLOCK_CHEST: case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_DAYLIGHT_SENSOR: case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: case E_BLOCK_ENCHANTMENT_TABLE: @@ -108,6 +109,7 @@ private: // Notice the lack of an E_BLOCK_ENDER_CHEST here; its because ender chests can totally be pushed/pulled in MCS :) case E_BLOCK_FURNACE: case E_BLOCK_LIT_FURNACE: + case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: case E_BLOCK_HOPPER: case E_BLOCK_JUKEBOX: case E_BLOCK_MOB_SPAWNER: -- cgit v1.2.3 From 0d2a041a69f741f10637ccc5a794075d05d1e03f Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 1 Oct 2014 19:13:59 +0200 Subject: Fixed Red Sandstone and Prismarine drops --- src/BlockID.h | 14 +++++++------- src/Items/ItemHandler.cpp | 1 + src/Items/ItemPickaxe.h | 39 ++++++++++++++++++++++----------------- 3 files changed, 30 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 9787b3bfa..984c782c4 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -555,10 +555,10 @@ enum E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_DEPRESSED = 1, - // E_BLOCK_PRISMARINE: - E_META_PRISMRAINE_ROUGH = 0, - E_META_PRISMARINE_BRICKS = 1, - E_META_PRISMARINE_DARK = 2, + // E_BLOCK_PRISMARINE_BLOCK metas: + E_META_PRISMRAINE_BLOCK_ROUGH = 0, + E_META_PRISMARINE_BLOCK_BRICKS = 1, + E_META_PRISMARINE_BLOCK_DARK = 2, // E_BLOCK_QUARTZ_BLOCK metas: E_META_QUARTZ_NORMAL = 0, @@ -577,7 +577,7 @@ enum E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XP = 9, - // E_BLOCK_RED_SANDSTONE: + // E_BLOCK_RED_SANDSTONE metas: E_META_RED_SANDSTONE_NORMAL = 0, E_META_RED_SANDSTONE_ORNAMENT = 1, E_META_RED_SANDSTONE_SMOOTH = 2, @@ -746,7 +746,7 @@ enum //////////////////////////////////////////////////////////////////////////////// // Item metas: - // E_ITEM_BANNER: + // E_ITEM_BANNER metas: E_META_BANNER_BLACK = 0, E_META_BANNER_RED = 1, E_META_BANNER_GREEN = 2, @@ -790,7 +790,7 @@ enum E_META_GOLDEN_APPLE_NORMAL = 0, E_META_GOLDEN_APPLE_ENCHANTED = 1, - // E_ITEM_HEAD: + // E_ITEM_HEAD metas: E_META_HEAD_SKELETON = 0, E_META_HEAD_WITHER = 1, E_META_HEAD_ZOMBIE = 2, diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index caa623abc..dbfba14a7 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -574,6 +574,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_COBBLESTONE_WALL: case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: case E_BLOCK_DOUBLE_STONE_SLAB: case E_BLOCK_EMERALD_ORE: case E_BLOCK_ENCHANTMENT_TABLE: diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index e0cf5d711..b5dc179f8 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -41,11 +41,11 @@ public: case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_EMERALD_ORE: case E_BLOCK_GOLD_BLOCK: case E_BLOCK_GOLD_ORE: case E_BLOCK_REDSTONE_ORE: case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_EMERALD_ORE: { return PickaxeLevel() >= 3; } @@ -59,29 +59,34 @@ public: } case E_BLOCK_ANVIL: - case E_BLOCK_ENCHANTMENT_TABLE: - case E_BLOCK_FURNACE: - case E_BLOCK_LIT_FURNACE: + case E_BLOCK_BRICK: + case E_BLOCK_CAULDRON: case E_BLOCK_COAL_ORE: - case E_BLOCK_STONE: case E_BLOCK_COBBLESTONE: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_COBBLESTONE_WALL: + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_ENCHANTMENT_TABLE: case E_BLOCK_END_STONE: + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + case E_BLOCK_MOB_SPAWNER: case E_BLOCK_MOSSY_COBBLESTONE: - case E_BLOCK_SANDSTONE_STAIRS: - case E_BLOCK_SANDSTONE: - case E_BLOCK_STONE_BRICKS: case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHER_BRICK_STAIRS: case E_BLOCK_NETHERRACK: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_BRICK: - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_COBBLESTONE_WALL: + case E_BLOCK_NEW_STONE_SLAB: + case E_BLOCK_PRISMARINE_BLOCK: + case E_BLOCK_RED_SANDSTONE: + case E_BLOCK_RED_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_STONE: + case E_BLOCK_STONE_BRICKS: case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_CAULDRON: - case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_STONE_SLAB: { return PickaxeLevel() >= 1; } -- cgit v1.2.3 From 3591edd47ee2290742b79e958439b475c1901c7c Mon Sep 17 00:00:00 2001 From: Masy98 Date: Wed, 1 Oct 2014 19:26:36 +0200 Subject: Fixed sorting --- src/Items/ItemHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index dbfba14a7..912dde022 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -588,6 +588,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_BLOCK: case E_BLOCK_LAPIS_ORE: case E_BLOCK_LIT_FURNACE: + case E_BLOCK_MOB_SPAWNER: case E_BLOCK_MOSSY_COBBLESTONE: case E_BLOCK_NETHER_BRICK: case E_BLOCK_NETHER_BRICK_STAIRS: @@ -595,6 +596,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_NETHERRACK: case E_BLOCK_NEW_STONE_SLAB: case E_BLOCK_OBSIDIAN: + case E_BLOCK_PACKED_ICE: case E_BLOCK_PRISMARINE_BLOCK: case E_BLOCK_RED_SANDSTONE: case E_BLOCK_RED_SANDSTONE_STAIRS: @@ -609,8 +611,6 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_STONE_SLAB: case E_BLOCK_VINES: - case E_BLOCK_PACKED_ICE: - case E_BLOCK_MOB_SPAWNER: { return false; } -- cgit v1.2.3 From 2f945475f2c031a1c60d5fe35cec17af82bde7f8 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Thu, 2 Oct 2014 07:22:12 +0100 Subject: Fix spelling of PRISMRAINE Fixes #1497 --- src/BlockID.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockID.h b/src/BlockID.h index 984c782c4..69b5e2fe0 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -556,7 +556,7 @@ enum E_META_PRESSURE_PLATE_DEPRESSED = 1, // E_BLOCK_PRISMARINE_BLOCK metas: - E_META_PRISMRAINE_BLOCK_ROUGH = 0, + E_META_PRISMARINE_BLOCK_ROUGH = 0, E_META_PRISMARINE_BLOCK_BRICKS = 1, E_META_PRISMARINE_BLOCK_DARK = 2, -- cgit v1.2.3 From 79e9de8d67e5fdf61c1f80794b5a31e6ac80e7a6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 3 Oct 2014 21:38:23 +0100 Subject: Comment suggestions --- src/Blocks/BlockTorch.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 3070adfd9..e77bbd1b8 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -37,6 +37,7 @@ public: a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Set a_BlockFace to a valid direction which will be converted later to a metadata if (a_BlockFace == BLOCK_FACE_NONE) { + // No attachable face found - don't place the torch return false; } } @@ -116,7 +117,7 @@ public: { if (cBlockInfo::FullyOccupiesVoxel(a_BlockType)) { - // Torches can be placed on full blocks unless their bottom side is clicked + // Torches can be placed on all sides of full blocks except the bottom return (a_BlockFace != BLOCK_FACE_YM); } return false; @@ -125,7 +126,7 @@ public: } - /// Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure + /** Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure */ static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all directions -- cgit v1.2.3 From f8c1da4a7178e7bb3d1bab3aaff7e326a855a0a8 Mon Sep 17 00:00:00 2001 From: win32re Date: Sat, 4 Oct 2014 14:02:40 +0200 Subject: Fixes #1503 - No gravel is being generated --- src/Generating/ComposableGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 4efcd1284..87461b944 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -422,7 +422,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) // Gravel vein cStructGenOreNests::OreInfo GravelVein; - GravelVein.BlockType = E_BLOCK_DIRT; + GravelVein.BlockType = E_BLOCK_GRAVEL; GravelVein.MaxHeight = 127; GravelVein.NumNests = 20; GravelVein.NestSize = 32; -- cgit v1.2.3 From ec71ffcc8015a9dccfa1d6f8dd474524412b605f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 5 Oct 2014 19:04:30 +0200 Subject: Added a cEvent::Wait() with timeout. --- src/OSSupport/Event.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/OSSupport/Event.h | 4 ++++ 2 files changed, 51 insertions(+) (limited to 'src') diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp index 74f823216..7cf8a826c 100644 --- a/src/OSSupport/Event.cpp +++ b/src/OSSupport/Event.cpp @@ -102,6 +102,53 @@ void cEvent::Wait(void) +bool cEvent::Wait(int a_TimeoutMSec) +{ + #ifdef _WIN32 + DWORD res = WaitForSingleObject(m_Event, (DWORD)a_TimeoutMSec); + switch (res) + { + case WAIT_OBJECT_0: return true; // Regular event signalled + case WAIT_TIMEOUT: return false; // Regular event timeout + default: + { + LOGWARN("cEvent: waiting for the event failed: %u, GLE = %u. Continuing, but server may be unstable.", (unsigned)res, (unsigned)GetLastError()); + return false; + } + } + #else + // Get the current time: + timespec timeout; + if (clock_gettime(CLOCK_REALTIME, &timeout) == -1) + { + LOGWARN("cEvent: Getting current time failed: %i, err = %s. Continuing, but the server may be unstable.", errno, GetOSErrorString(errno).c_str()); + return false; + } + + // Add the specified timeout: + timeout.tv_sec += a_TimeoutMSec / 1000; + timeout.tv_nsec += (a_TimeoutMSec % 1000) * 1000000; // 1 msec = 1000000 usec + + // Wait with timeout: + int res = sem_timedwait(m_Event, &timeout); + switch (res) + { + case 0: return true; // Regular event signalled + case ETIMEDOUT: return false; // Regular even timeout + default: + { + AString error = GetOSErrorString(errno); + LOGWARN("cEvent: waiting for the event failed: %i, err = %s. Continuing, but server may be unstable.", res, error.c_str()); + return false; + } + } + #endif +} + + + + + void cEvent::Set(void) { #ifdef _WIN32 diff --git a/src/OSSupport/Event.h b/src/OSSupport/Event.h index 71f418c0c..e2fa65a05 100644 --- a/src/OSSupport/Event.h +++ b/src/OSSupport/Event.h @@ -24,6 +24,10 @@ public: void Wait(void); void Set (void); + + /** Waits for the event until either it is signalled, or the (relative) timeout is passed. + Returns true if the event was signalled, false if the timeout was hit or there was an error. */ + bool Wait(int a_TimeoutMSec); private: -- cgit v1.2.3 From a8aeceab9d6e5e5e36ef7bd58783b65aca4d8be7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 5 Oct 2014 20:19:21 +0200 Subject: cClientHandle: Added protocol version knowledge. --- src/ClientHandle.cpp | 12 ++++++++++-- src/ClientHandle.h | 9 +++++++++ src/Protocol/ProtocolRecognizer.cpp | 1 + src/Protocol/ProtocolRecognizer.h | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index a29bef0c0..3b677460b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -92,7 +92,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_NumBlockChangeInteractionsThisTick(0), m_UniqueID(0), m_HasSentPlayerChunk(false), - m_Locale("en_GB") + m_Locale("en_GB"), + m_ProtocolVersion(0) { m_Protocol = new cProtocolRecognizer(this); @@ -583,15 +584,22 @@ void cClientHandle::HandlePing(void) bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Username) { + // If the protocol version hasn't been set yet, set it now: + if (m_ProtocolVersion == 0) + { + m_ProtocolVersion = a_ProtocolVersion; + } + m_Username = a_Username; + // Let the plugins know about this event, they may refuse the player: if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) { Destroy(); return false; } - // Schedule for authentication; until then, let them wait (but do not block) + // Schedule for authentication; until then, let the player wait (but do not block) m_State = csAuthenticating; cRoot::Get()->GetAuthenticator().Authenticate(GetUniqueID(), GetUsername(), m_Protocol->GetAuthServerID()); return true; diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 20592c190..a9cc29d50 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -316,6 +316,12 @@ public: /** Called when the player will enchant a Item */ void HandleEnchantItem(Byte & a_WindowID, Byte & a_Enchantment); + + /** Called by the protocol recognizer when the protocol version is known. */ + void SetProtocolVersion(UInt32 a_ProtocolVersion) { m_ProtocolVersion = a_ProtocolVersion; } + + /** Returns the protocol version number of the protocol that the client is talking. Returns zero if the protocol version is not (yet) known. */ + UInt32 GetProtocolVersion(void) const { return m_ProtocolVersion; } // tolua_export private: @@ -427,6 +433,9 @@ private: /** The brand identification of the client, as received in the MC|Brand plugin message or set from a plugin. */ AString m_ClientBrand; + /** The version of the protocol that the client is talking, or 0 if unknown. */ + UInt32 m_ProtocolVersion; + /** 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, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler); diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 4f8eb59db..15bcd03b1 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -905,6 +905,7 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema { return false; } + m_Client->SetProtocolVersion(ProtocolVersion); switch (ProtocolVersion) { case PROTO_VERSION_1_7_2: diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 96a7e17d2..b42cfdec2 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -134,7 +134,7 @@ protected: /// Tries to recognize protocol based on m_Buffer contents; returns true if recognized bool TryRecognizeProtocol(void); - /** Tries to recognize a protocol in the leghted family (1.7+), based on m_Buffer; returns true if recognized. + /** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer; returns true if recognized. The packet length and type have already been read, type is 0 The number of bytes remaining in the packet is passed as a_PacketLengthRemaining **/ -- cgit v1.2.3 From 77c5b410e653433a17c7cf25b115dae4c25bdbd2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 5 Oct 2014 22:09:19 +0200 Subject: Fixed eMonsterType Lua API mismatch. --- src/Bindings/AllToLua.pkg | 1 + src/BlockID.cpp | 51 ----------------------------------------------- src/BlockID.h | 3 --- src/Mobs/CMakeLists.txt | 1 + src/Mobs/Monster.cpp | 10 ++++++++++ src/Mobs/MonsterTypes.h | 13 ++++++++++++ 6 files changed, 25 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 37e6aecd2..73de98e22 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -27,6 +27,7 @@ $cfile "WebPlugin.h" $cfile "LuaWindow.h" $cfile "../BlockID.h" +$cfile "../Mobs/MonsterTypes.h" $cfile "../BlockInfo.h" $cfile "../StringUtils.h" $cfile "../Defines.h" diff --git a/src/BlockID.cpp b/src/BlockID.cpp index 9026d81f2..755c721db 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -253,57 +253,6 @@ AString ItemToFullString(const cItem & a_Item) -int StringToMobType(const AString & a_MobString) -{ - static struct - { - int m_MobType; - const char * m_String; - } MobMap [] = - { - {mtCreeper, "Creeper"}, - {mtSkeleton, "Skeleton"}, - {mtSpider, "Spider"}, - {mtGiant, "Giant"}, - {mtZombie, "Zombie"}, - {mtSlime, "Slime"}, - {mtGhast, "Ghast"}, - {mtZombiePigman, "ZombiePigman"}, - {mtEnderman, "Enderman"}, - {mtCaveSpider, "CaveSpider"}, - {mtSilverfish, "SilverFish"}, - {mtBlaze, "Blaze"}, - {mtMagmaCube, "MagmaCube"}, - {mtEnderDragon, "EnderDragon"}, - {mtWither, "Wither"}, - {mtBat, "Bat"}, - {mtWitch, "Witch"}, - {mtPig, "Pig"}, - {mtSheep, "Sheep"}, - {mtCow, "Cow"}, - {mtChicken, "Chicken"}, - {mtSquid, "Squid"}, - {mtWolf, "Wolf"}, - {mtMooshroom, "Mooshroom"}, - {mtSnowGolem, "SnowGolem"}, - {mtOcelot, "Ocelot"}, - {mtIronGolem, "IronGolem"}, - {mtVillager, "Villager"}, - }; - for (size_t i = 0; i < ARRAYCOUNT(MobMap); i++) - { - if (NoCaseCompare(MobMap[i].m_String, a_MobString) == 0) - { - return MobMap[i].m_MobType; - } - } // for i - MobMap[] - return -1; -} - - - - - eDimension StringToDimension(const AString & a_DimensionString) { // First try decoding as a number diff --git a/src/BlockID.h b/src/BlockID.h index 69b5e2fe0..e36843422 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -1005,9 +1005,6 @@ extern AString ItemTypeToString(short a_ItemType); /// Translates a full item into a fully-specified string (including meta and count). If the ItemType is not recognized, the ItemType number is output into the string. extern AString ItemToFullString(const cItem & a_Item); -/// Translates a mob string ("ocelot") to mobtype (E_ENTITY_TYPE_OCELOT) -extern int StringToMobType(const AString & a_MobString); - /// Translates a dimension string to dimension enum. Takes either a number or a dimension alias (built-in). Returns dimOverworld on failure extern eDimension StringToDimension(const AString & a_DimensionString); diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt index 2c092c15f..bbbb9287a 100644 --- a/src/Mobs/CMakeLists.txt +++ b/src/Mobs/CMakeLists.txt @@ -54,6 +54,7 @@ SET (HDRS IronGolem.h MagmaCube.h Monster.h + MonsterTypes.h Mooshroom.h Ocelot.h PassiveAggressiveMonster.h diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 12ca6bbbe..cc48dba5e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -62,6 +62,16 @@ static const struct +eMonsterType StringToMobType(const AString & a_MobString) +{ + LOGWARNING("%s: Function is obsolete, use cMonster::StringToMobType() instead"); + return cMonster::StringToMobType(a_MobString); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cMonster: diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h index 7a73e99f4..852eb3446 100644 --- a/src/Mobs/MonsterTypes.h +++ b/src/Mobs/MonsterTypes.h @@ -37,5 +37,18 @@ enum eMonsterType mtZombie = E_META_SPAWN_EGG_ZOMBIE, mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN, } ; + + + + + +/** Translates a mob string ("ocelot") to mobtype (mtOcelot). +OBSOLETE, use cMonster::StringToMobType() instead. +Implemented in Monster.cpp. */ +extern eMonsterType StringToMobType(const AString & a_MobString); + // tolua_end + + + -- cgit v1.2.3 From 112fac579829edf32e41da6da4bd8a98e5b6f0bd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 5 Oct 2014 22:12:25 +0200 Subject: Removed obsolete cMonster::eType. Has been replaced with global eMonsterType. --- src/Mobs/Monster.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index a1f9c4a5b..9fd67d67c 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -25,9 +25,6 @@ class cMonster : typedef cPawn super; public: - // Deprecated - typedef eMonsterType eType; - enum eFamily { mfHostile = 0, // Spider, Zombies ... -- cgit v1.2.3 From c94e82980e0c21f9a7ed18c5f3279e63849e8433 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 5 Oct 2014 22:56:56 +0200 Subject: Fixed a missed value. --- src/Mobs/Monster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index cc48dba5e..73dbcb3c3 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -64,7 +64,7 @@ static const struct eMonsterType StringToMobType(const AString & a_MobString) { - LOGWARNING("%s: Function is obsolete, use cMonster::StringToMobType() instead"); + LOGWARNING("%s: Function is obsolete, use cMonster::StringToMobType() instead", __FUNCTION__); return cMonster::StringToMobType(a_MobString); } -- cgit v1.2.3 From a20bd0dbbd9c107a47049ce83f0b050384fd7b19 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 5 Oct 2014 23:44:55 +0100 Subject: Update CMakeLists.txt --- src/OSSupport/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/OSSupport/CMakeLists.txt b/src/OSSupport/CMakeLists.txt index a42fcbed4..429949c59 100644 --- a/src/OSSupport/CMakeLists.txt +++ b/src/OSSupport/CMakeLists.txt @@ -39,6 +39,6 @@ if(NOT MSVC) add_library(OSSupport ${SRCS} ${HDRS}) if(UNIX) - target_link_libraries(OSSupport pthread) + target_link_libraries(OSSupport pthread rt) endif() endif() -- cgit v1.2.3 From 3d2d8a096b72a0af9d4e21198d112d97c9318410 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 5 Oct 2014 20:03:21 +0200 Subject: cMojangAPI: Added periodical refreshes. --- src/Protocol/MojangAPI.cpp | 130 ++++++++++++++++++++++++++++++++++++++------- src/Protocol/MojangAPI.h | 21 ++++++++ 2 files changed, 132 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 28da83c31..0a6716e6f 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -11,6 +11,8 @@ #include "json/json.h" #include "PolarSSL++/BlockingSslClientSocket.h" #include "../RankManager.h" +#include "../OSSupport/IsThread.h" +#include "../Root.h" @@ -151,6 +153,41 @@ cMojangAPI::sProfile::sProfile( +//////////////////////////////////////////////////////////////////////////////// +// cMojangAPI::cUpdateThread: + +class cMojangAPI::cUpdateThread : + public cIsThread +{ + typedef cIsThread super; +public: + cUpdateThread() : + super("cMojangAPI::cUpdateThread") + { + } + + ~cUpdateThread() + { + m_evtNotify.Set(); + Stop(); + } + +protected: + cEvent m_evtNotify; + + virtual void Execute(void) override + { + do + { + cRoot::Get()->GetMojangAPI().Update(); + } while (!m_evtNotify.Wait(60 * 60 * 1000)); // Repeat every 60 minutes + } +} ; + + + + + //////////////////////////////////////////////////////////////////////////////// // cMojangAPI: @@ -159,7 +196,8 @@ cMojangAPI::cMojangAPI(void) : m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_UUIDToProfileServer(DEFAULT_UUID_TO_PROFILE_SERVER), m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS), - m_RankMgr(NULL) + m_RankMgr(NULL), + m_UpdateThread(new cUpdateThread()) { } @@ -183,6 +221,7 @@ void cMojangAPI::Start(cIniFile & a_SettingsIni) m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER); m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS); LoadCachesFromDisk(); + m_UpdateThread->Start(); } @@ -465,21 +504,7 @@ void cMojangAPI::LoadCachesFromDisk(void) db.exec("CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)"); db.exec("CREATE TABLE IF NOT EXISTS UUIDToProfile (UUID, PlayerName, Textures, TexturesSignature, DateTime)"); - // Clean up old entries: - { - SQLite::Statement stmt(db, "DELETE FROM PlayerNameToUUID WHERE DateTime < ?"); - Int64 LimitDateTime = time(NULL) - MAX_AGE; - stmt.bind(1, LimitDateTime); - stmt.exec(); - } - { - SQLite::Statement stmt(db, "DELETE FROM UUIDToProfile WHERE DateTime < ?"); - Int64 LimitDateTime = time(NULL) - MAX_AGE; - stmt.bind(1, LimitDateTime); - stmt.exec(); - } - - // Retrieve all remaining entries: + // Retrieve all entries: { SQLite::Statement stmt(db, "SELECT PlayerName, UUID, DateTime FROM PlayerNameToUUID"); while (stmt.executeStep()) @@ -596,18 +621,27 @@ void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) } // for itr - a_PlayerNames[] } // Lock(m_CSNameToUUID) - while (!NamesToQuery.empty()) + QueryNamesToUUIDs(NamesToQuery); +} + + + + + +void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery) +{ + while (!a_NamesToQuery.empty()) { // Create the request body - a JSON containing up to MAX_PER_QUERY playernames: Json::Value root; int Count = 0; - AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); + AStringVector::iterator itr = a_NamesToQuery.begin(), end = a_NamesToQuery.end(); for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count) { Json::Value req(*itr); root.append(req); } // for itr - a_PlayerNames[] - NamesToQuery.erase(NamesToQuery.begin(), itr); + a_NamesToQuery.erase(a_NamesToQuery.begin(), itr); Json::FastWriter Writer; AString RequestBody = Writer.write(root); @@ -705,12 +739,22 @@ void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) // Check if already present: { + cCSLock Lock(m_CSUUIDToProfile); if (m_UUIDToProfile.find(a_UUID) != m_UUIDToProfile.end()) { return; } } + QueryUUIDToProfile(a_UUID); +} + + + + + +void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID) +{ // Create the request address: AString Address = m_UUIDToProfileAddress; ReplaceString(Address, "%UUID%", a_UUID); @@ -817,3 +861,51 @@ void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_ + +void cMojangAPI::Update(void) +{ + Int64 LimitDateTime = time(NULL) - MAX_AGE; + + // Re-query all playernames that are stale: + AStringVector PlayerNames; + { + cCSLock Lock(m_CSNameToUUID); + for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr) + { + if (itr->second.m_DateTime < LimitDateTime) + { + PlayerNames.push_back(itr->first); + } + } // for itr - m_NameToUUID[] + } + if (!PlayerNames.empty()) + { + LOG("cMojangAPI: Updating name-to-uuid cache for %u names", (unsigned)PlayerNames.size()); + QueryNamesToUUIDs(PlayerNames); + } + + // Re-query all profiles that are stale: + AStringVector ProfileUUIDs; + { + cCSLock Lock(m_CSUUIDToProfile); + for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr) + { + if (itr->second.m_DateTime < LimitDateTime) + { + ProfileUUIDs.push_back(itr->first); + } + } // for itr - m_UUIDToProfile[] + } + if (!ProfileUUIDs.empty()) + { + LOG("cMojangAPI: Updating uuid-to-profile cache for %u uuids", (unsigned)ProfileUUIDs.size()); + for (AStringVector::const_iterator itr = ProfileUUIDs.begin(), end = ProfileUUIDs.end(); itr != end; ++itr) + { + QueryUUIDToProfile(*itr); + } + } +} + + + + diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index 252d32543..fa4c16e4e 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -93,6 +93,10 @@ public: void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; } protected: + /** The thread that periodically checks for stale data and re-queries it from the server. */ + class cUpdateThread; + + /** Holds data for a single player profile. */ struct sProfile { @@ -177,6 +181,9 @@ protected: /** Protects m_RankMgr agains simultaneous multi-threaded access. */ cCriticalSection m_CSRankMgr; + + /** The thread that periodically updates the stale data in the DB from the Mojang servers. */ + SharedPtr m_UpdateThread; /** Loads the caches from a disk storage. */ @@ -189,15 +196,29 @@ protected: Names that are not valid are not added into the cache. ASSUMEs that a_PlayerNames contains lowercased player names. */ void CacheNamesToUUIDs(const AStringVector & a_PlayerNames); + + /** Queries all the specified names and stores them into the m_PlayerNameToUUID cache. + Names that are not valid are not added into the cache. + ASSUMEs that a_PlayerNames contans lowercased player names. + For performance reasons takes a non-const reference and modifies the list given to it, until empty. */ + void QueryNamesToUUIDs(AStringVector & a_PlayerNames); /** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers. UUIDs that are not valid will not be added into the cache. ASSUMEs that a_UUID is a lowercased short UUID. */ void CacheUUIDToProfile(const AString & a_UUID); + /** Queries the specified UUID's profile and stores it in the m_UUIDToProfile cache. If already present, updates the cache entry. + UUIDs that are not valid will not be added into the cache. + ASSUMEs that a_UUID is a lowercased short UUID. */ + void QueryUUIDToProfile(const AString & a_UUID); + /** Called for each name-uuid pairing that is discovered. If assigned, notifies the m_RankManager of the event. */ void NotifyNameUUID(const AString & a_PlayerName, const AString & a_PlayerUUID); + + /** Updates the stale values in the DB from the Mojang servers. Called from the cUpdateThread, blocks on the HTTPS API calls. */ + void Update(void); } ; // tolua_export -- cgit v1.2.3 From 4e82a580602226e37aae0b1c361e71e4ce47ef52 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 6 Oct 2014 13:48:44 +0200 Subject: Fixed crash in ForEachEntityInBox API. Fixes #1511. --- src/Bindings/LuaState.cpp | 14 +++++++++++--- src/Bindings/LuaState.h | 2 +- src/Bindings/ManualBindings.cpp | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index ba2f3c5e0..85e3f9fc5 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -861,6 +861,11 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal) void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) { + if (lua_isnil(m_LuaState, a_StackPos)) + { + a_ReturnedVal = NULL; + return; + } tolua_Error err; if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err)) { @@ -874,6 +879,11 @@ void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal) void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal) { + if (lua_isnil(m_LuaState, a_StackPos)) + { + a_ReturnedVal = NULL; + return; + } tolua_Error err; if (tolua_isusertype(m_LuaState, a_StackPos, "cWorld", false, &err)) { @@ -1396,10 +1406,8 @@ void cLuaState::LogStack(const char * a_Header) void cLuaState::LogStack(lua_State * a_LuaState, const char * a_Header) { - UNUSED(a_Header); // The param seems unused when compiling for release, so the compiler warns - // Format string consisting only of %s is used to appease the compiler - LOGD("%s", (a_Header != NULL) ? a_Header : "Lua C API Stack contents:"); + LOG("%s", (a_Header != NULL) ? a_Header : "Lua C API Stack contents:"); for (int i = lua_gettop(a_LuaState); i > 0; i--) { AString Value; diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 094a200e0..ef87c3efc 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -304,7 +304,7 @@ public: void ToString(int a_StackPos, AString & a_String); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ - void LogStack(const char * a_Header); + void LogStack(const char * a_Header = NULL); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f4764447c..f643f06ec 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -697,8 +697,12 @@ static int tolua_ForEachInBox(lua_State * tolua_S) Ty1 * Self = NULL; cBoundingBox * Box = NULL; L.GetStackValues(1, Self, Box); - ASSERT(Self != NULL); // We have verified the type at the top, so we should get valid objects here - ASSERT(Box != NULL); + if ((Self == NULL) || (Box == NULL)) + { + LOGWARNING("Invalid world (%p) or boundingbox (%p)", Self, Box); + L.LogStackTrace(); + return 0; + } // Create a reference for the function: cLuaState::cRef FnRef(L, 3); -- cgit v1.2.3 From e3a69a527d53fd7540dce4a424d280a9d0cbb1a9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 7 Oct 2014 15:02:51 +0200 Subject: Removed unused cBlockHayBaleHandler. --- src/Blocks/BlockHandler.cpp | 3 +-- src/Blocks/BlockHayBale.h | 22 ---------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 src/Blocks/BlockHayBale.h (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index ff0b201e7..904e0a921 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -36,7 +36,6 @@ #include "BlockGlass.h" #include "BlockGlowstone.h" #include "BlockGravel.h" -#include "BlockHayBale.h" #include "BlockMobHead.h" #include "BlockHopper.h" #include "BlockIce.h" @@ -231,7 +230,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType); - case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType); + case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType); case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType); case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType); diff --git a/src/Blocks/BlockHayBale.h b/src/Blocks/BlockHayBale.h deleted file mode 100644 index 8150b10d3..000000000 --- a/src/Blocks/BlockHayBale.h +++ /dev/null @@ -1,22 +0,0 @@ - -#pragma once - -#include "BlockSideways.h" - - - - - -class cBlockHayBaleHandler : - public cBlockSidewaysHandler -{ -public: - cBlockHayBaleHandler(BLOCKTYPE a_BlockType) - : cBlockSidewaysHandler(a_BlockType) - { - } -} ; - - - - -- cgit v1.2.3 From fec509935dce9c51d597c58cba2acdd558d7ae53 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 7 Oct 2014 15:39:24 +0200 Subject: Removed BlockHaybale.h from CMakeLists.txt --- src/Blocks/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index 9f971a8bd..eed949aab 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -45,7 +45,6 @@ SET (HDRS BlockGlowstone.h BlockGravel.h BlockHandler.h - BlockHayBale.h BlockHopper.h BlockIce.h BlockLadder.h -- cgit v1.2.3 From 68a54c90c9408f2b3351e778a632b024e1433984 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 8 Oct 2014 20:31:16 +0200 Subject: Added AcaciaTrees for the savanna biomes --- src/Generating/Trees.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 1b0f2dc14..c78a30f9b 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -224,8 +224,6 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No case biMegaTaiga: case biMegaTaigaHills: case biExtremeHillsPlus: - case biSavanna: - case biSavannaPlateau: case biMesa: case biMesaPlateauF: case biMesaPlateau: @@ -241,8 +239,6 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No case biMegaSpruceTaiga: case biMegaSpruceTaigaHills: case biExtremeHillsPlusM: - case biSavannaM: - case biSavannaPlateauM: case biMesaBryce: case biMesaPlateauFM: case biMesaPlateauM: @@ -252,6 +248,15 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No return; } + case biSavanna: + case biSavannaPlateau: + case biSavannaM: + case biSavannaPlateauM: + { + GetAcaciaTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); + return; + } + case biRoofedForest: case biRoofedForestM: { @@ -403,7 +408,53 @@ void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { - // TODO + int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 11 % 3); + + // Create the trunk + for (int i = 0; i < Height; i++) + { + a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); + } + + Vector3i BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); + Vector3i BranchDirection = Vector3i(a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY, a_BlockZ) % 3 - 1, 0, a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ * a_Seq) % 3 - 1); + int Attempts = 0; + while (BranchDirection.Length() == 0.0) + { + Attempts++; + BranchDirection = Vector3i(a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * Attempts, a_BlockZ) % 3 - 1, 0, a_Noise.IntNoise3DInt(a_BlockX, a_BlockY * Attempts, a_BlockZ * a_Seq) % 3 - 1); + } + BranchDirection.y = 1; + + int BranchHeight = a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 3 + 1; + for (int i = 0; i < BranchHeight; i++) + { + BranchPos = BranchPos + BranchDirection; + a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); + } + + PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); + PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); + a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD)); + + bool TwoTop = (a_Noise.IntNoise3D(a_BlockX, a_BlockY, a_BlockZ) < 0 ? true : false); + if (!TwoTop) + { + return; + } + + BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); + BranchDirection = Vector3d(-BranchDirection.x, 1, -BranchDirection.z); + BranchHeight = a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * a_Seq * 10, a_BlockZ * a_Seq) % 3 + 1; + for (int i = 0; i < BranchHeight; i++) + { + BranchPos = BranchPos + BranchDirection; + a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); + } + + PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); + PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); + a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD)); } -- cgit v1.2.3 From 36fa1c5c73ba273051904d539e82d1f8f33a50d7 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 8 Oct 2014 21:25:59 +0200 Subject: Using array with possible directions. --- src/Generating/Trees.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index c78a30f9b..8fce61b95 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -416,15 +416,16 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); } - Vector3i BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); - Vector3i BranchDirection = Vector3i(a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY, a_BlockZ) % 3 - 1, 0, a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ * a_Seq) % 3 - 1); - int Attempts = 0; - while (BranchDirection.Length() == 0.0) + const Vector3i AvailableDirections[] = { - Attempts++; - BranchDirection = Vector3i(a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * Attempts, a_BlockZ) % 3 - 1, 0, a_Noise.IntNoise3DInt(a_BlockX, a_BlockY * Attempts, a_BlockZ * a_Seq) % 3 - 1); - } - BranchDirection.y = 1; + { -1, 1, 0 }, { 0, 1, -1 }, + { -1, 1, 1 }, { -1, 1, -1 }, + { 1, 1, 1 }, { 1, 1, -1 }, + { 1, 1, 0 }, { 0, 1, 1 }, + }; + + Vector3i BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); + Vector3i BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 8]; int BranchHeight = a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 3 + 1; for (int i = 0; i < BranchHeight; i++) -- cgit v1.2.3 From e95ee55974b674d7f026bae3beac7836da74efba Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 8 Oct 2014 21:32:09 +0200 Subject: Added comments to the GetAcaciaTreeImage function --- src/Generating/Trees.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 8fce61b95..7fd6d6f07 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -408,6 +408,7 @@ void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { + // Calculate a base height int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 11 % 3); // Create the trunk @@ -416,6 +417,7 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); } + // Array with possible directions for a branch to go to. const Vector3i AvailableDirections[] = { { -1, 1, 0 }, { 0, 1, -1 }, @@ -424,35 +426,51 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi { 1, 1, 0 }, { 0, 1, 1 }, }; + // Set the starting point of the branch Vector3i BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); + + // Get a direction for the trunk to go to. Vector3i BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 8]; + // Calculate a height for the branch between 1 and 3 int BranchHeight = a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 3 + 1; + + // Place the logs of the branch. for (int i = 0; i < BranchHeight; i++) { BranchPos = BranchPos + BranchDirection; a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); } + // Add the leaves to the top of the branch PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD)); + // Choose if we have to add another branch bool TwoTop = (a_Noise.IntNoise3D(a_BlockX, a_BlockY, a_BlockZ) < 0 ? true : false); if (!TwoTop) { return; } + // Reset the starting point of the branch BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ); + + // Invert the direction of the previous branch. BranchDirection = Vector3d(-BranchDirection.x, 1, -BranchDirection.z); + + // Calculate a new height for the second branch BranchHeight = a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * a_Seq * 10, a_BlockZ * a_Seq) % 3 + 1; + + // Place the logs in the same way as the first branch for (int i = 0; i < BranchHeight; i++) { BranchPos = BranchPos + BranchDirection; a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD)); } + // And add the leaves ontop of the second branch PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD); a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD)); -- cgit v1.2.3 From f91aa6f1d3c38f68ccf157731f1d1c3c6beda2ee Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 9 Oct 2014 12:33:16 +0200 Subject: DistortedHeightmap: Fixed crash on number rounding. Fixes #1521. --- src/Generating/DistortedHeightmap.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index c18c402da..bf8995dcb 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -540,10 +540,11 @@ void cDistortedHeightmap::InitializeCompoGen(cIniFile & a_IniFile) int cDistortedHeightmap::GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z) { - int ChunkX = (int)floor(a_X / (NOISE_DATATYPE)16); - int ChunkZ = (int)floor(a_Z / (NOISE_DATATYPE)16); - int RelX = (int)(a_X - (NOISE_DATATYPE)ChunkX * cChunkDef::Width); - int RelZ = (int)(a_Z - (NOISE_DATATYPE)ChunkZ * cChunkDef::Width); + int RelX = (int)std::floor(a_X); + int RelY = 0; + int RelZ = (int)std::floor(a_Z); + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); // If we're withing the same chunk, return the pre-cached heightmap: if ((ChunkX == m_CurChunkX) && (ChunkZ == m_CurChunkZ)) -- cgit v1.2.3 From f8d1e96ae7ac9a3483ff0a214796455946d7880f Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 3 Sep 2014 16:25:45 -0700 Subject: Use static casts instead of C casts, add floor-cast functions --- src/Entities/Entity.h | 6 +++--- src/Globals.h | 40 ++++++++++++++++++++++++++++++++++++---- src/Vector3.h | 33 ++++++++++++++++----------------- 3 files changed, 55 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 3fa7e80c1..0a03eb3f2 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -27,9 +27,9 @@ return super::GetClass(); \ } -#define POSX_TOINT (int)floor(GetPosX()) -#define POSY_TOINT (int)floor(GetPosY()) -#define POSZ_TOINT (int)floor(GetPosZ()) +#define POSX_TOINT FloorD(GetPosX()) +#define POSY_TOINT FloorD(GetPosY()) +#define POSZ_TOINT FloorD(GetPosZ()) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) #define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } diff --git a/src/Globals.h b/src/Globals.h index 0926457da..8bf7a0f0c 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -226,10 +226,10 @@ template class SizeChecker; // CRT stuff: #include -#include -#include -#include -#include +#include +#include +#include +#include @@ -400,6 +400,38 @@ T Clamp(T a_Value, T a_Min, T a_Max) +/** Floors a_Value, then casts it to C (an int by default) */ +template +C FloorD(double a_Value) +{ + return static_cast(std::floor(a_Value)); +} + +/** Floors a_Value, then casts it to C (an int by default) */ +template +C FloorF(double a_Value) +{ + return static_cast(std::floorf(a_Value)); +} + +/** Ciels a_Value, then casts it to C (an int by default) */ +template +C CeilD(double a_Value) +{ + return static_cast(std::ceil(a_Value)); +} + +/** Ciels a_Value, then casts it to C (an int by default) */ +template +C CeilF(double a_Value) +{ + return static_cast(std::ceilf(a_Value)); +} + + + + + #ifndef TOLUA_TEMPLATE_BIND #define TOLUA_TEMPLATE_BIND(x) #endif diff --git a/src/Vector3.h b/src/Vector3.h index 1dcb38f64..782b0d1c9 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -4,7 +4,6 @@ #define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) -#include #include #include @@ -29,9 +28,9 @@ public: // Hardcoded copy constructors (tolua++ does not support function templates .. yet) - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} + Vector3(const Vector3 & a_Rhs) : x(static_cast(a_Rhs.x)), y(static_cast(a_Rhs.y)), z(static_cast(a_Rhs.z)) {} // tolua_end @@ -53,9 +52,9 @@ public: { double Len = 1.0 / Length(); - x = (T)(x * Len); - y = (T)(y * Len); - z = (T)(z * Len); + x = static_cast(x * Len); + y = static_cast(y * Len); + z = static_cast(z * Len); } inline Vector3 NormalizeCopy(void) const @@ -63,9 +62,9 @@ public: double Len = 1.0 / Length(); return Vector3( - (T)(x * Len), - (T)(y * Len), - (T)(z * Len) + static_cast(x * Len), + static_cast(y * Len), + static_cast(z * Len) ); } @@ -74,15 +73,15 @@ public: double Len = 1.0 / Length(); a_Rhs.Set( - (T)(x * Len), - (T)(y * Len), - (T)(z * Len) + static_cast(x * Len), + static_cast(y * Len), + static_cast(z * Len) ); } inline double Length(void) const { - return sqrt((double)(x * x + y * y + z * z)); + return sqrt(static_cast(x * x + y * y + z * z)); } inline double SqrLength(void) const @@ -138,9 +137,9 @@ public: inline Vector3 Floor(void) const { return Vector3( - (int)floor(x), - (int)floor(y), - (int)floor(z) + static_cast(floor(x)), + static_cast(floor(y)), + static_cast(floor(z)) ); } -- cgit v1.2.3 From 76b37acb421bf10e094182b2e9be111eb29c46f1 Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 3 Sep 2014 16:51:38 -0700 Subject: Float/Ciel: If it's going to use C++11, it might as well take advantage of it --- src/Entities/Entity.h | 6 +++--- src/Globals.h | 26 ++++++-------------------- src/Vector3.h | 6 +++--- 3 files changed, 12 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 0a03eb3f2..f0577aba2 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -27,9 +27,9 @@ return super::GetClass(); \ } -#define POSX_TOINT FloorD(GetPosX()) -#define POSY_TOINT FloorD(GetPosY()) -#define POSZ_TOINT FloorD(GetPosZ()) +#define POSX_TOINT FloorC(GetPosX()) +#define POSY_TOINT FloorC(GetPosY()) +#define POSZ_TOINT FloorC(GetPosZ()) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) #define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } diff --git a/src/Globals.h b/src/Globals.h index 8bf7a0f0c..9959d92a9 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -400,34 +400,20 @@ T Clamp(T a_Value, T a_Min, T a_Max) -/** Floors a_Value, then casts it to C (an int by default) */ -template -C FloorD(double a_Value) +/** Floors a value, then casts it to C (an int by default) */ +template +typename std::enable_if::value, C>::type FloorC(T a_Value) { return static_cast(std::floor(a_Value)); } -/** Floors a_Value, then casts it to C (an int by default) */ -template -C FloorF(double a_Value) -{ - return static_cast(std::floorf(a_Value)); -} - -/** Ciels a_Value, then casts it to C (an int by default) */ -template -C CeilD(double a_Value) +/** Ceils a value, then casts it to C (an int by default) */ +template +typename std::enable_if::value, C>::type CeilC(T a_Value) { return static_cast(std::ceil(a_Value)); } -/** Ciels a_Value, then casts it to C (an int by default) */ -template -C CeilF(double a_Value) -{ - return static_cast(std::ceilf(a_Value)); -} - diff --git a/src/Vector3.h b/src/Vector3.h index 782b0d1c9..937c8fdfa 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -137,9 +137,9 @@ public: inline Vector3 Floor(void) const { return Vector3( - static_cast(floor(x)), - static_cast(floor(y)), - static_cast(floor(z)) + FloorC(x), + FloorC(y), + FloorC(z) ); } -- cgit v1.2.3 From a47d9e53344144d7584c37bbac742cf2187492fe Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 10 Oct 2014 09:58:54 +0200 Subject: Fixed MSVC compilation. --- src/Globals.h | 3 +++ src/Vector3.h | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Globals.h b/src/Globals.h index 9959d92a9..4ee1352eb 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -51,6 +51,9 @@ #define NORETURN __declspec(noreturn) + // Use non-standard defines in + #define _USE_MATH_DEFINES + #elif defined(__GNUC__) // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? diff --git a/src/Vector3.h b/src/Vector3.h index 937c8fdfa..1854e42e3 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -3,7 +3,6 @@ -#define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) #include #include -- cgit v1.2.3