From b5e898a608cfa0b872828db842e31ec2d624e598 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 21:12:44 +0000 Subject: Server now handles join messages also * Revised as well hook documentation --- MCServer/Plugins/APIDump/Hooks/OnDisconnect.lua | 16 ++++++---------- MCServer/Plugins/APIDump/Hooks/OnPlayerDestroyed.lua | 10 +++++++--- MCServer/Plugins/APIDump/Hooks/OnPlayerJoined.lua | 8 ++++---- src/ClientHandle.cpp | 20 +++++++++++--------- src/Entities/Player.cpp | 8 +++++++- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnDisconnect.lua b/MCServer/Plugins/APIDump/Hooks/OnDisconnect.lua index 496e0d751..a3301a8c6 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnDisconnect.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnDisconnect.lua @@ -5,13 +5,10 @@ return CalledWhen = "A player has explicitly disconnected.", DefaultFnName = "OnDisconnect", -- also used as pagename Desc = [[ - This hook is called when a client sends the disconnect packet and is about to be disconnected from - the server.

-

- Note that this callback is not called if the client drops the connection or is kicked by the - server.

-

- FIXME: There is no callback for "client destroying" that would be called in all circumstances.

+ This hook is called when a client is about to be disconnected from the server, for whatever reason. + +

Note that this hook will be removed after <1.7 protocol support is removed, as it was originally a hook for + the client sending the server a disconnect packet, which no longer happens.

]], Params = { @@ -19,9 +16,8 @@ return { Name = "Reason", Type = "string", Notes = "The reason that the client has sent in the disconnect packet" }, }, Returns = [[ - If the function returns false or no value, MCServer calls other plugins' callbacks for this event - and finally broadcasts a disconnect message to the player's world. If the function returns true, no - other plugins are called for this event and the disconnect message is not broadcast. In either case, + If the function returns false or no value, MCServer calls other plugins' callbacks for this event. + If the function returns true, no other plugins are called for this event. In either case, the player is disconnected. ]], }, -- HOOK_DISCONNECT diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerDestroyed.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerDestroyed.lua index 8e503658c..dc033197a 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerDestroyed.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerDestroyed.lua @@ -2,17 +2,21 @@ return { HOOK_PLAYER_DESTROYED = { - CalledWhen = "A player is about to get destroyed.", + CalledWhen = "A player object is about to be destroyed.", DefaultFnName = "OnPlayerDestroyed", -- also used as pagename Desc = [[ - This function is called when a {{cPlayer|player}} is about to get destroyed. But the player isn't already destroyed. + This function is called before a {{cPlayer|player}} is about to be destroyed. + The player has disconnected for whatever reason and is no longer in the server. + If a plugin returns true, a leave message is not broadcast, and vice versa. + However, whatever the return value, the player object is removed from memory. ]], Params = { { Name = "Player", Type = "{{cPlayer}}", Notes = "The destroyed player" }, }, Returns = [[ - It's only for notification. Can't be returned. + If the function returns false or no value, other plugins' callbacks are called and a leave message is broadcast. + If the function returns true, no other callbacks are called for this event and no leave message appears. Either way the player is removed internally. ]], }, -- HOOK_PLAYER_DESTROYED } diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerJoined.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerJoined.lua index 00805af7e..dcd16ed00 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerJoined.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerJoined.lua @@ -9,16 +9,16 @@ return enabled, this function is called after their name has been authenticated. It is called after {{OnLogin|HOOK_LOGIN}} and before {{OnPlayerSpawned|HOOK_PLAYER_SPAWNED}}, right after the player's entity is created, but not added to the world yet. The player is not yet visible to other players. - This is a notification-only event, plugins wishing to refuse player's entry should kick the player - using the {{cPlayer}}:Kick() function. + Returning true will block a join message from being broadcast, but otherwise, the player is still allowed to join. + Plugins wishing to refuse player's entry should kick the player using the {{cPlayer}}:Kick() function. ]], Params = { { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has joined the game" }, }, Returns = [[ - If the function returns false or no value, other plugins' callbacks are called. If the function - returns true, no other callbacks are called for this event. Either way the player is let in. + If the function returns false or no value, other plugins' callbacks are called and a join message is broadcast. If the function + returns true, no other callbacks are called for this event and a join message is not sent. Either way the player is let in. ]], }, -- HOOK_PLAYER_JOINED } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6b61eaae8..b0eb27089 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -227,7 +227,13 @@ void cClientHandle::Authenticate(void) m_Player->SetIP (m_IPString); - cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player); + if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player)) + { + AString JoinMessage; + AppendPrintf(JoinMessage, "%s[JOIN] %s%s has joined the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), m_Username.c_str()); + cRoot::Get()->BroadcastChat(JoinMessage); + LOGINFO("Player %s has joined the game.", m_Username.c_str()); + } m_ConfirmPosition = m_Player->GetPosition(); @@ -910,7 +916,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, c cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable()) + if (ItemHandler->IsPlaceable() && (a_BlockFace > -1)) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1330,13 +1336,9 @@ 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()); - if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason)) - { - AString DisconnectMessage; - Printf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), m_Username.c_str()); - cRoot::Get()->BroadcastChat(DisconnectMessage); - LOGINFO("Player %s has left the game.", m_Username.c_str()); - } + + cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason); + m_HasSentDC = true; Destroy(); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8c37fdc8d..a1c942c20 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -130,7 +130,13 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) cPlayer::~cPlayer(void) { - cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this); + if (!cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this)) + { + AString DisconnectMessage; + AppendPrintf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetClientHandle()->GetUsername().c_str()); + cRoot::Get()->BroadcastChat(DisconnectMessage); + LOGINFO("Player %s has left the game.", GetClientHandle()->GetUsername().c_str()); + } LOGD("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); -- cgit v1.2.3 From 6bbba2644d520204c50b48d67ca294fcd9b0a5c4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 21:14:52 +0000 Subject: Fixed issues with farmland * Fixed farmland reversion checks not taking into account carrots and potatoes * Fixed #623 --- src/Blocks/BlockCrops.h | 2 +- src/Blocks/BlockFarmland.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index 4c4ac21be..ffc2b3f8b 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -87,7 +87,7 @@ public: if ((Meta < 7) && (Light > 8)) { - a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_CROPS, ++Meta); + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++Meta); } else if (Light < 9) { diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h index 101ab8e34..b720ccd14 100644 --- a/src/Blocks/BlockFarmland.h +++ b/src/Blocks/BlockFarmland.h @@ -90,6 +90,8 @@ public: switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)) { case E_BLOCK_CROPS: + case E_BLOCK_POTATOES: + case E_BLOCK_CARROTS: case E_BLOCK_MELON_STEM: case E_BLOCK_PUMPKIN_STEM: { -- cgit v1.2.3 From 3fc848c95a7e16ac759dc74f32ea7e7b0f46de6e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 21:16:26 +0000 Subject: Fixed #626 * Fixed consumption of carrots and potatoes --- src/Items/ItemFood.h | 6 +++--- src/Items/ItemHandler.cpp | 25 +++++++++++++++---------- src/Items/ItemSeeds.h | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 2ae572331..961cf482d 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -31,7 +31,7 @@ public: // Please keep alpha-sorted. case E_ITEM_BAKED_POTATO: return FoodInfo(6, 7.2); case E_ITEM_BREAD: return FoodInfo(5, 6); - case E_ITEM_CARROT: return FoodInfo(4, 4.8); + // 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_PORKCHOP: return FoodInfo(8, 12.8); @@ -39,8 +39,9 @@ public: case E_ITEM_GOLDEN_APPLE: return FoodInfo(4, 9.6); 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_POTATO: return FoodInfo(1, 0.6); + // 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); @@ -50,7 +51,6 @@ public: 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_STEAK: return FoodInfo(8, 12.8); - case E_ITEM_MUSHROOM_SOUP: return FoodInfo(6, 7.2); } 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 302796d1b..9024aafea 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -181,23 +181,28 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) return new cItemMinecartHandler(a_ItemType); } - // Food: + // Food (please keep alpha-sorted): + // (carrots and potatoes handled in SeedHandler as both seed and food + case E_ITEM_BAKED_POTATO: case E_ITEM_BREAD: + case E_ITEM_COOKED_CHICKEN: + 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_RAW_CHICKEN: - case E_ITEM_COOKED_CHICKEN: + case E_ITEM_MUSHROOM_SOUP: + case E_ITEM_POISONOUS_POTATO: + case E_ITEM_PUMPKIN_PIE: case E_ITEM_RAW_BEEF: - case E_ITEM_RAW_PORKCHOP: - case E_ITEM_STEAK: - case E_ITEM_COOKED_PORKCHOP: + case E_ITEM_RAW_CHICKEN: case E_ITEM_RAW_FISH: - case E_ITEM_COOKED_FISH: + case E_ITEM_RAW_PORKCHOP: case E_ITEM_RED_APPLE: - case E_ITEM_GOLDEN_APPLE: case E_ITEM_ROTTEN_FLESH: - case E_ITEM_MUSHROOM_SOUP: case E_ITEM_SPIDER_EYE: + case E_ITEM_STEAK: { return new cItemFoodHandler(a_ItemType); } @@ -511,7 +516,7 @@ bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) cItemHandler::FoodInfo cItemHandler::GetFoodInfo() { - return FoodInfo(0, 0.f); + return FoodInfo(0, 0); } diff --git a/src/Items/ItemSeeds.h b/src/Items/ItemSeeds.h index 67f0d38bd..3e20e2d56 100644 --- a/src/Items/ItemSeeds.h +++ b/src/Items/ItemSeeds.h @@ -22,6 +22,26 @@ public: { return true; } + + virtual bool IsFood(void) override + { + switch (m_ItemType) // Special cases, both a seed and food + { + case E_ITEM_CARROT: + case E_ITEM_POTATO: return true; + default: return false; + } + } + + virtual FoodInfo GetFoodInfo(void) override + { + switch (m_ItemType) + { + case E_ITEM_CARROT: return FoodInfo(4, 4.8); + case E_ITEM_POTATO: return FoodInfo(1, 0.6); + default: return FoodInfo(0, 0); + } + } virtual bool GetPlacementBlockTypeMeta( cWorld * a_World, cPlayer * a_Player, -- cgit v1.2.3 From 6de8c09fe0044f310397ef94457277f7426470e0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:24:22 +0000 Subject: Fixed a crash bug --- src/ClientHandle.cpp | 10 ++-------- src/Entities/Player.cpp | 6 +++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b0eb27089..3e9e03815 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -230,7 +230,7 @@ void cClientHandle::Authenticate(void) if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player)) { AString JoinMessage; - AppendPrintf(JoinMessage, "%s[JOIN] %s%s has joined the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), m_Username.c_str()); + AppendPrintf(JoinMessage, "%s[JOIN] %s%s has joined the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetUsername().c_str()); cRoot::Get()->BroadcastChat(JoinMessage); LOGINFO("Player %s has joined the game.", m_Username.c_str()); } @@ -2461,13 +2461,7 @@ void cClientHandle::SocketClosed(void) if (m_Username != "") // Ignore client pings { - if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, "Player disconnected")) - { - AString DisconnectMessage; - Printf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), m_Username.c_str()); - cRoot::Get()->BroadcastChat(DisconnectMessage); - LOGINFO("Player %s has left the game.", m_Username.c_str()); - } + cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, "Player disconnected"); } Destroy(); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index d649cacf2..70c881091 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -133,12 +133,12 @@ cPlayer::~cPlayer(void) if (!cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this)) { AString DisconnectMessage; - AppendPrintf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetClientHandle()->GetUsername().c_str()); + AppendPrintf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetName().c_str()); cRoot::Get()->BroadcastChat(DisconnectMessage); - LOGINFO("Player %s has left the game.", GetClientHandle()->GetUsername().c_str()); + LOGINFO("Player %s has left the game.", GetName().c_str()); } - LOGD("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); + LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), this, GetUniqueID()); // Notify the server that the player is being destroyed cRoot::Get()->GetServer()->PlayerDestroying(this); -- cgit v1.2.3 From fad90081d2c039a2c34badf16ba48e0ae80bc014 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:25:16 +0000 Subject: Fixed #491 --- src/OSSupport/File.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 0ebd04915..17070030f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -73,14 +73,26 @@ bool cFile::Open(const AString & iFileName, eMode iMode) return false; } } - m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), Mode); + +#ifdef _WIN32 + fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), Mode); +#else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode); +#endif // _WIN32 + if ((m_File == NULL) && (iMode == fmReadWrite)) { // Fix for MS not following C spec, opening "a" mode files for writing at the end only // The file open operation has been tried with "read update", fails if file not found // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. // Simply re-open for read-writing, erasing existing contents: - m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), "wb+"); + +#ifdef _WIN32 + fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), "wb+"); +#else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+"); +#endif // _WIN32 + } return (m_File != NULL); } -- cgit v1.2.3 From d82f3102e59bec9a0eb45b3731a82c92e2d11b59 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:26:16 +0000 Subject: Partial fix for #130 --- src/WorldStorage/NBTChunkSerializer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index c6250f393..95b5e66d2 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -625,6 +625,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break; + case cEntity::etTNT: /* TODO */ break; case cEntity::etExpOrb: /* TODO */ break; case cEntity::etPlayer: return; // Players aren't saved into the world default: -- cgit v1.2.3 From 3583a58cf7bbeb867e568f4210f270cd5058e9f3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:46:56 +0000 Subject: Added SendMessageXXX() to cPlayer As requested by @bearbin, one no longer needs to download a file that links to Core. The server does it! Hopefully this encourages standards compliance. --- src/Defines.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/Entities/Player.h | 3 +++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/Defines.h b/src/Defines.h index 5b868b2e5..17885394e 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -1,6 +1,8 @@ #pragma once +#include "ChatColor.h" + @@ -441,7 +443,73 @@ inline float GetSpecialSignf( float a_Val ) -// tolua_begin +enum ChatPrefixCodes +{ + // http://forum.mc-server.org/showthread.php?tid=1212 + // MessageType... + + mtCustom, // Plugin prints what it wants + mtFailure, // Something could not be done (i.e. command not executed due to insufficient privilege) + mtInformation, // Informational message (i.e. command usage) + mtSuccess, // Something executed successfully + mtWarning, // Something concerning (i.e. reload) is about to happen + mtFatal, // Something catastrophic occured (i.e. plugin crash) + mtDeath, // Denotes death of player + mtPrivateMessage // Player to player messaging identifier +}; + + + + +inline AString AppendChatEpithet(const AString & a_ChatMessage, ChatPrefixCodes a_ChatPrefix) +{ + switch (a_ChatPrefix) + { + case mtCustom: return a_ChatMessage; + case mtFailure: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtInformation: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtSuccess: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtWarning: + { + AString Message(Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtFatal: + { + AString Message(Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtDeath: + { + AString Message(Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtPrivateMessage: + { + AString Message(Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str())); + Message.append(a_ChatMessage); + return Message; + } + } +}// tolua_begin /// Normalizes an angle in degrees to the [-180, +180) range: inline double NormalizeAngleDegrees(const double a_Degrees) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 50f7560d6..764b47ae0 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -196,6 +196,9 @@ public: cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } void SendMessage(const AString & a_Message); + void SendMessageInfo(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtInformation)); } + void SendMessageFailure(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } + void SendMessageSuccess(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtSuccess)); } const AString & GetName(void) const { return m_PlayerName; } void SetName(const AString & a_Name) { m_PlayerName = a_Name; } -- cgit v1.2.3 From 01c723e89eb364b9245386bcdd2902b287ee2982 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:51:26 +0000 Subject: Pickup constructor no longer exported It didn't do anything without Initialize() exported, anyway, pickups are spawned with cWorld. --- src/Entities/ExpOrb.h | 1 + src/Entities/Floater.h | 4 +++- src/Entities/Pickup.h | 7 ++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index a062eedd3..47d86922c 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -13,6 +13,7 @@ class cExpOrb : typedef cExpOrb super; public: + CLASS_PROTODEF(cExpOrb); cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward); cExpOrb(const Vector3d & a_Pos, int a_Reward); diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h index 162b74e75..865d6dc50 100644 --- a/src/Entities/Floater.h +++ b/src/Entities/Floater.h @@ -14,8 +14,10 @@ class cFloater : typedef cFloater super; public: - //tolua_end + + CLASS_PROTODEF(cFloater); + cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, int a_PlayerID, int a_CountDownTime); virtual void SpawnOn(cClientHandle & a_Client) override; diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h index d39eda298..c273567d1 100644 --- a/src/Entities/Pickup.h +++ b/src/Entities/Pickup.h @@ -18,15 +18,16 @@ class cPlayer; class cPickup : public cEntity { - // tolua_end typedef cEntity super; public: + // tolua_end + CLASS_PROTODEF(cPickup); - cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); // tolua_export + cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); - cItem & GetItem(void) {return m_Item; } // tolua_export + cItem & GetItem(void) {return m_Item; } // tolua_export const cItem & GetItem(void) const {return m_Item; } virtual void SpawnOn(cClientHandle & a_ClientHandle) override; -- cgit v1.2.3 From 9eeeb91fa6e3df67aa1dc8aae54da8e6631d25be Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 22:39:57 +0000 Subject: Added more SendMessageXXX() functions --- src/Defines.h | 91 ++++++++++++++++++++++++++------------------------- src/Entities/Player.h | 4 +++ src/Root.h | 14 ++++++-- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index 17885394e..f766d4d04 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -465,51 +465,54 @@ inline AString AppendChatEpithet(const AString & a_ChatMessage, ChatPrefixCodes { switch (a_ChatPrefix) { - case mtCustom: return a_ChatMessage; - case mtFailure: - { - AString Message(Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtInformation: - { - AString Message(Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtSuccess: - { - AString Message(Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtWarning: - { - AString Message(Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtFatal: - { - AString Message(Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtDeath: - { - AString Message(Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; - } - case mtPrivateMessage: - { - AString Message(Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str())); - Message.append(a_ChatMessage); - return Message; - } + case mtCustom: return a_ChatMessage; + case mtFailure: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtInformation: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtSuccess: + { + AString Message(Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtWarning: + { + AString Message(Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtFatal: + { + AString Message(Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtDeath: + { + AString Message(Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str())); + Message.append(a_ChatMessage); + return Message; + } + case mtPrivateMessage: + { + AString Message(Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str())); + Message.append(a_ChatMessage); + return Message; + } + default: ASSERT(!"Unhandled chat prefix type!"); return ""; } -}// tolua_begin +} + +// tolua_begin /// Normalizes an angle in degrees to the [-180, +180) range: inline double NormalizeAngleDegrees(const double a_Degrees) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 764b47ae0..784aac327 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -199,6 +199,10 @@ public: void SendMessageInfo(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtInformation)); } void SendMessageFailure(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } void SendMessageSuccess(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtSuccess)); } + void SendMessageWarning(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtWarning)); } + void SendMessageFatal(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } + void SendMessageDeath(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtDeath)); } + void SendMessagePrivateMsg(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtPrivateMessage)); } const AString & GetName(void) const { return m_PlayerName; } void SetName(const AString & a_Name) { m_PlayerName = a_Name; } diff --git a/src/Root.h b/src/Root.h index c59afc810..fa52c21a1 100644 --- a/src/Root.h +++ b/src/Root.h @@ -3,6 +3,7 @@ #include "Authenticator.h" #include "HTTPServer/HTTPServer.h" +#include "Defines.h" @@ -98,9 +99,6 @@ public: /// Saves all chunks in all worlds void SaveAllChunks(void); // tolua_export - /// Sends a chat message to all connected clients (in all worlds) - void BroadcastChat(const AString & a_Message); // tolua_export - /// Calls the callback for each player in all worlds bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << @@ -109,6 +107,16 @@ public: // tolua_begin + /// Sends a chat message to all connected clients (in all worlds) + void BroadcastChat(const AString & a_Message); + void BroadcastChatInfo(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtInformation)); } + void BroadcastChatFailure(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } + void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtSuccess)); } + void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtWarning)); } + void BroadcastChatFatal(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } + void BroadcastChatDeath(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtDeath)); } + void BroadcastChatPrivateMsg(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtPrivateMessage)); } + /// 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 630507fd5b8a7ac280ee75994f98b9ecfdcb7a70 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:07:22 +0000 Subject: Fixed a bunch of MSVS warnings * Possibly also fixed some bugs with pathfinding and TNT, though unlikely --- src/Blocks/BlockButton.h | 2 +- src/Blocks/BlockLever.h | 2 +- src/Blocks/BlockTrapdoor.h | 4 ++-- src/ChunkMap.cpp | 2 +- src/Mobs/Monster.cpp | 2 +- src/Protocol/Protocol17x.cpp | 3 ++- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index f592b94a1..5567c1942 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -88,7 +88,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return BLOCK_FACE_NONE; + return 0; } } } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 09b600759..cb65cd03c 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -88,7 +88,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return BLOCK_FACE_NONE; + return 0; } } } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index f549b4183..ee595d9c4 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -68,7 +68,7 @@ public: default: { ASSERT(!"Unhandled block face!"); - return 0x0; + return 0; } } } @@ -84,7 +84,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return BLOCK_FACE_NONE; + return 0; } } } diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 1e2181f32..cb10e275d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1839,7 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSize, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSizeInt, ExplosionSizeSq); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 283ef36e6..b49a8661d 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -264,7 +264,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) { m_Destination.y = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z); - if (DoesPosYRequireJump(m_Destination.y)) + if (DoesPosYRequireJump((int)floor(m_Destination.y))) { m_bOnGround = false; AddPosY(1.5); // Jump!! diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 04bade867..eb42e9299 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2435,7 +2435,8 @@ void cProtocol172::cPacketizer::WriteEntityProperties(const cEntity & a_Entity) WriteInt(0); return; } - const cMonster & Mob = (const cMonster &)a_Entity; + + //const cMonster & Mob = (const cMonster &)a_Entity; // TODO: Send properties and modifiers based on the mob type -- cgit v1.2.3 From ea2ce1595f51c141342991378c372529f26434c6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:27:13 +0000 Subject: Fixed annoying creative on fire bug --- src/Entities/Player.cpp | 17 +++++++++++++++++ src/Entities/Player.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 70c881091..c0466fa66 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1760,6 +1760,23 @@ void cPlayer::UseEquippedItem(void) +void cPlayer::TickBurning(cChunk & a_Chunk) +{ + // Don't burn in creative and stop burning in creative if necessary + if (!IsGameModeCreative()) + { + super::TickBurning(a_Chunk); + } + else if (IsOnFire()) + { + m_TicksLeftBurning = 0; + OnFinishedBurning(); + } +} + + + + void cPlayer::HandleFood(void) { diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 784aac327..925011c9c 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -475,6 +475,9 @@ protected: /// Filters out damage for creative mode/friendly fire virtual void DoTakeDamage(TakeDamageInfo & TDI) override; + + /** Stops players from burning in creative mode */ + virtual void TickBurning(cChunk & a_Chunk) override; /// Called in each tick to handle food-related processing void HandleFood(void); -- cgit v1.2.3 From 94c343fe079346caf24be265234cce194bc3b450 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:40:58 +0000 Subject: Fixed explosions bug * Fixed bug where explosions would sometimes never be sent --- src/ChunkMap.cpp | 2 +- src/ClientHandle.cpp | 30 ++++++++++-------------------- src/ClientHandle.h | 13 ++----------- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index cb10e275d..db2a1b1d9 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1839,7 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSizeInt, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt, ExplosionSizeSq); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3e9e03815..3059ae7b1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -44,16 +44,13 @@ -/// If the number of queued outgoing packets reaches this, the client will be kicked +/** If the number of queued outgoing packets reaches this, the client will be kicked */ #define MAX_OUTGOING_PACKETS 2000 -/// How many explosions per single game tick are allowed -static const int MAX_EXPLOSIONS_PER_TICK = 100; +/** Maximum number of explosions to send this tick, server will start dropping if exceeded */ +#define MAX_EXPLOSIONS_PER_TICK 100 -/// How many explosions in the recent history are allowed -static const int MAX_RUNNING_SUM_EXPLOSIONS = cClientHandle::NUM_CHECK_EXPLOSIONS_TICKS * MAX_EXPLOSIONS_PER_TICK / 8; - -/// How many ticks before the socket is closed after the client is destroyed (#31) +/** How many ticks before the socket is closed after the client is destroyed (#31) */ static const int TICKS_BEFORE_CLOSE = 20; @@ -95,8 +92,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_TicksSinceDestruction(0), m_State(csConnected), m_ShouldCheckDownloaded(false), - m_CurrentExplosionTick(0), - m_RunningSumExplosions(0), + m_NumExplosionsThisTick(0), m_UniqueID(0), m_HasSentPlayerChunk(false) { @@ -1637,10 +1633,8 @@ void cClientHandle::Tick(float a_Dt) } } - // Update the explosion statistics: - m_CurrentExplosionTick = (m_CurrentExplosionTick + 1) % ARRAYCOUNT(m_NumExplosionsPerTick); - m_RunningSumExplosions -= m_NumExplosionsPerTick[m_CurrentExplosionTick]; - m_NumExplosionsPerTick[m_CurrentExplosionTick] = 0; + // Reset explosion counter: + m_NumExplosionsThisTick = 0; } @@ -1920,18 +1914,14 @@ void cClientHandle::SendEntityVelocity(const cEntity & a_Entity) void cClientHandle::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { - if ( - (m_NumExplosionsPerTick[m_CurrentExplosionTick] > MAX_EXPLOSIONS_PER_TICK) || // Too many explosions in this tick - (m_RunningSumExplosions > MAX_RUNNING_SUM_EXPLOSIONS) // Too many explosions in the recent history - ) + if (m_NumExplosionsThisTick > MAX_EXPLOSIONS_PER_TICK) { - LOGD("Dropped %u explosions", a_BlocksAffected.size()); + LOGD("Dropped an explosion!"); return; } // Update the statistics: - m_NumExplosionsPerTick[m_CurrentExplosionTick] += a_BlocksAffected.size(); - m_RunningSumExplosions += a_BlocksAffected.size(); + m_NumExplosionsThisTick += 1; m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index e1f326543..29a56f5a7 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -53,9 +53,6 @@ public: static const int MAX_VIEW_DISTANCE = 15; static const int MIN_VIEW_DISTANCE = 3; - /// How many ticks should be checked for a running average of explosions, for limiting purposes - static const int NUM_CHECK_EXPLOSIONS_TICKS = 20; - cClientHandle(const cSocket * a_Socket, int a_ViewDistance); virtual ~cClientHandle(); @@ -301,14 +298,8 @@ private: /// If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded() bool m_ShouldCheckDownloaded; - /// Stores the recent history of the number of explosions per tick - int m_NumExplosionsPerTick[NUM_CHECK_EXPLOSIONS_TICKS]; - - /// Points to the current tick in the m_NumExplosionsPerTick[] array - int m_CurrentExplosionTick; - - /// Running sum of m_NumExplosionsPerTick[] - int m_RunningSumExplosions; + /** Number of explosions sent this tick */ + int m_NumExplosionsThisTick; static int s_ClientCount; int m_UniqueID; -- cgit v1.2.3 From 7d151d54946fe3c82c053faf02a06b32b0be563f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:53:10 +0000 Subject: Updated Core & PolarSSL --- MCServer/Plugins/Core | 2 +- lib/polarssl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 5fe3662a8..fbe438b61 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 5fe3662a8719f79cb2ca0a16150c716a3c5eb19c +Subproject commit fbe438b61bef3fc350f1ba1fa24a130506115bf0 diff --git a/lib/polarssl b/lib/polarssl index c78c8422c..2cb1a0c40 160000 --- a/lib/polarssl +++ b/lib/polarssl @@ -1 +1 @@ -Subproject commit c78c8422c25b9dc38f09eded3200d565375522e2 +Subproject commit 2cb1a0c4009ecf368ecc74eb428394e10f9e6d00 -- cgit v1.2.3 From 99fdadd58e459b70803fff5f9fd3cae1ab8df2d5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 Feb 2014 00:45:08 +0000 Subject: Reduced max explosions per tick --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3059ae7b1..439f980ce 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -48,7 +48,7 @@ #define MAX_OUTGOING_PACKETS 2000 /** Maximum number of explosions to send this tick, server will start dropping if exceeded */ -#define MAX_EXPLOSIONS_PER_TICK 100 +#define MAX_EXPLOSIONS_PER_TICK 20 /** How many ticks before the socket is closed after the client is destroyed (#31) */ static const int TICKS_BEFORE_CLOSE = 20; -- cgit v1.2.3 From 3450f0ca42c8f72920045709d0a57d5443b086a7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 Feb 2014 23:24:02 +0000 Subject: Added more chat functions --- src/Defines.h | 56 +++++++++++++++++++++++++++++---------------------- src/Entities/Player.h | 1 - src/Root.h | 4 +++- src/World.h | 12 ++++++++++- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index f766d4d04..7fe93399d 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -448,14 +448,15 @@ enum ChatPrefixCodes // http://forum.mc-server.org/showthread.php?tid=1212 // MessageType... - mtCustom, // Plugin prints what it wants mtFailure, // Something could not be done (i.e. command not executed due to insufficient privilege) mtInformation, // Informational message (i.e. command usage) mtSuccess, // Something executed successfully mtWarning, // Something concerning (i.e. reload) is about to happen mtFatal, // Something catastrophic occured (i.e. plugin crash) mtDeath, // Denotes death of player - mtPrivateMessage // Player to player messaging identifier + mtPrivateMessage, // Player to player messaging identifier + mtJoin, // A player has joined the server + mtLeave, // A player has left the server }; @@ -463,53 +464,60 @@ enum ChatPrefixCodes inline AString AppendChatEpithet(const AString & a_ChatMessage, ChatPrefixCodes a_ChatPrefix) { + AString Message; + switch (a_ChatPrefix) { - case mtCustom: return a_ChatMessage; case mtFailure: { - AString Message(Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); + break; } case mtInformation: { - AString Message(Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + break; } case mtSuccess: { - AString Message(Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str()); + break; } case mtWarning: { - AString Message(Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); + break; } case mtFatal: { - AString Message(Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str()); + break; } case mtDeath: { - AString Message(Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str()); + break; } case mtPrivateMessage: { - AString Message(Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str())); - Message.append(a_ChatMessage); - return Message; + Message = Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str()); + break; + } + case mtJoin: + { + Message = Printf("%s[JOIN] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + break; + } + case mtLeave: + { + Message = Printf("%s[LEAVE] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + break; } default: ASSERT(!"Unhandled chat prefix type!"); return ""; } + + Message.append(a_ChatMessage); + return Message; } // tolua_begin diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 925011c9c..f2830a0c7 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -201,7 +201,6 @@ public: void SendMessageSuccess(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtSuccess)); } void SendMessageWarning(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtWarning)); } void SendMessageFatal(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } - void SendMessageDeath(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtDeath)); } void SendMessagePrivateMsg(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtPrivateMessage)); } const AString & GetName(void) const { return m_PlayerName; } diff --git a/src/Root.h b/src/Root.h index fa52c21a1..ba106b54e 100644 --- a/src/Root.h +++ b/src/Root.h @@ -104,6 +104,9 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + + void BroadcastChatJoin(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtJoin)); } + void BroadcastChatLeave(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtLeave)); } // tolua_begin @@ -115,7 +118,6 @@ public: void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtWarning)); } void BroadcastChatFatal(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } void BroadcastChatDeath(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtDeath)); } - void BroadcastChatPrivateMsg(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtPrivateMessage)); } /// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum); diff --git a/src/World.h b/src/World.h index bf6a4ba28..01481c049 100644 --- a/src/World.h +++ b/src/World.h @@ -157,7 +157,17 @@ public: void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude - void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export + + // tolua_start + void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); + void BroadcastChatInfo(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtInformation)); } + void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } + void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtSuccess)); } + void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtWarning)); } + void BroadcastChatFatal(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } + void BroadcastChatDeath(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtDeath)); } + // tolua_end + void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); -- cgit v1.2.3 From aa8b46e94714f261bfe451897b7ef23934e764eb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 Feb 2014 23:24:16 +0000 Subject: Server internally uses new functions --- src/Bindings/PluginManager.cpp | 4 ++-- src/Blocks/BlockBed.cpp | 2 +- src/ClientHandle.cpp | 14 ++++++-------- src/Entities/Player.cpp | 10 ++++------ 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index a20583550..c6c8c081e 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -248,7 +248,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { AStringVector Split(StringSplit(a_Message, " ")); ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long - a_Player->SendMessage(Printf("%s[INFO] %sUnknown command: \"%s\"", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), Split[0].c_str())); + a_Player->SendMessageInfo(Printf("Unknown command: \"%s\"", Split[0].c_str())); LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player->GetName().c_str(), a_Message.c_str()); return true; // Cancel sending } @@ -1392,7 +1392,7 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command !a_Player->HasPermission(cmd->second.m_Permission) ) { - a_Player->SendMessage(Printf("%s[INFO] %sForbidden command; insufficient privileges: \"%s\"", cChatColor::Rose.c_str(), cChatColor::White.c_str(), Split[0].c_str())); + a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); a_WasCommandForbidden = true; return false; diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index 65d397b36..8f291ad1f 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -78,7 +78,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface } } } else { - a_Player->SendMessage("You can only sleep at night"); + a_Player->SendMessageFailure("You can only sleep at night"); } } } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 439f980ce..f7c6cb734 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -225,9 +225,7 @@ void cClientHandle::Authenticate(void) if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player)) { - AString JoinMessage; - AppendPrintf(JoinMessage, "%s[JOIN] %s%s has joined the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetUsername().c_str()); - cRoot::Get()->BroadcastChat(JoinMessage); + cRoot::Get()->BroadcastChatJoin(Printf("%s has joined the game", GetUsername().c_str())); LOGINFO("Player %s has joined the game.", m_Username.c_str()); } @@ -568,7 +566,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a { if (a_Length < 14) { - SendChat(Printf("%s[INFO]%s Failure setting command block command; bad request", cChatColor::Red.c_str(), cChatColor::White.c_str())); + SendChat(AppendChatEpithet("Failure setting command block command; bad request", mtFailure)); LOGD("Malformed MC|AdvCdm packet."); return; } @@ -598,7 +596,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a default: { - SendChat(Printf("%s[INFO]%s Failure setting command block command; unhandled mode", cChatColor::Red.c_str(), cChatColor::White.c_str())); + SendChat(AppendChatEpithet("Failure setting command block command; unhandled mode", mtFailure)); LOGD("Unhandled MC|AdvCdm packet mode."); return; } @@ -609,12 +607,12 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a if (World->AreCommandBlocksEnabled()) { World->SetCommandBlockCommand(BlockX, BlockY, BlockZ, Command); - - SendChat(Printf("%s[INFO]%s Successfully set command block command", cChatColor::Green.c_str(), cChatColor::White.c_str())); + + SendChat(AppendChatEpithet("Successfully set command block command", mtSuccess)); } else { - SendChat(Printf("%s[INFO]%s Command blocks are not enabled on this server", cChatColor::Yellow.c_str(), cChatColor::White.c_str())); + SendChat(AppendChatEpithet("Command blocks are not enabled on this server", mtFailure)); } } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c0466fa66..385e28c28 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -132,9 +132,7 @@ cPlayer::~cPlayer(void) { if (!cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this)) { - AString DisconnectMessage; - AppendPrintf(DisconnectMessage, "%s[LEAVE] %s%s has left the game", cChatColor::Yellow.c_str(), cChatColor::White.c_str(), GetName().c_str()); - cRoot::Get()->BroadcastChat(DisconnectMessage); + cRoot::Get()->BroadcastChatLeave(Printf("%s has left the game", GetName().c_str())); LOGINFO("Player %s has left the game.", GetName().c_str()); } @@ -847,18 +845,18 @@ void cPlayer::KilledBy(cEntity * a_Killer) if (a_Killer == NULL) { - GetWorld()->BroadcastChat(Printf("%s[DEATH] %s%s was killed by environmental damage", cChatColor::Red.c_str(), cChatColor::White.c_str(), GetName().c_str())); + GetWorld()->BroadcastChatDeath(Printf("%s was killed by environmental damage", GetName().c_str())); } else if (a_Killer->IsPlayer()) { - GetWorld()->BroadcastChat(Printf("%s[DEATH] %s%s was killed by %s", cChatColor::Red.c_str(), cChatColor::White.c_str(), GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str())); + GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str())); } else { AString KillerClass = a_Killer->GetClass(); KillerClass.erase(KillerClass.begin()); // Erase the 'c' of the class (e.g. "cWitch" -> "Witch") - GetWorld()->BroadcastChat(Printf("%s[DEATH] %s%s was killed by a %s", cChatColor::Red.c_str(), cChatColor::White.c_str(), GetName().c_str(), KillerClass.c_str())); + GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } class cIncrementCounterCB -- cgit v1.2.3 From 88a64ec40df87f21a89de43fe8bb78f10ee7eeb7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 7 Feb 2014 18:58:52 +0000 Subject: Improved chat messaging functions * Moved string manipulation into cClientHandle and therefore... + Added configuration option for prefixes. * Cleaned up code. * Updated documentation for API. --- MCServer/Plugins/APIDump/APIDesc.lua | 27 ++++++++- src/ClientHandle.cpp | 114 +++++++++++++++++++++++++++++++++-- src/ClientHandle.h | 2 +- src/Defines.h | 64 +------------------- src/Entities/Player.cpp | 10 --- src/Entities/Player.h | 15 ++--- src/Root.cpp | 4 +- src/Root.h | 19 +++--- src/World.cpp | 11 ++-- src/World.h | 27 ++++++--- 10 files changed, 179 insertions(+), 114 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index cbdb7797b..69e1bdda9 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1644,7 +1644,13 @@ a_Player:OpenWindow(Window); OpenWindow = { Params = "{{cWindow|Window}}", Return = "", Notes = "Opens the specified UI window for the player." }, RemoveFromGroup = { Params = "GroupName", Return = "", Notes = "Temporarily removes the player from the specified group. This change is lost when the player disconnects." }, Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." }, - SendMessage = { Params = "MessageString", Return = "", Notes = "Sends the specified message to the player." }, + SendMessage = { Params = "Message", Return = "", Notes = "Sends the specified message to the player." }, + SendMessageFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For a command that failed to run because of insufficient permissions, etc." }, + SendMessageFatal = { Params = "Message", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For something serious, such as a plugin crash, etc." }, + SendMessageInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Informational message, such as command usage, etc." }, + SendMessagePrivateMsg = { Params = "Message, SenderName", Return = "", Notes = "Prepends Light Blue [MSG: *SenderName*] / prepends SenderName and colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For private messaging." }, + SendMessageSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Success notification." }, + SendMessageWarning = { Params = "Message, Sender", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Denotes that something concerning, such as plugin reload, is about to happen." }, SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." }, SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." }, SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." }, @@ -1823,7 +1829,12 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); Functions = { Get = { Params = "", Return = "Root object", Notes = "(STATIC)This function returns the cRoot object." }, - BroadcastChat = { Params = "Message", Return = "", Notes = "Broadcasts a message to every player in the server." }, + BroadcastChat = { Params = "Message", Return = "", Notes = "Broadcasts a message to every player in the server. No formatting is done by the server." }, + BroadcastChatFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a command that failed to run because of insufficient permissions, etc." }, + BroadcastChatFatal = { Params = "Message", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a plugin that crashed, or similar." }, + BroadcastChatInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." }, + BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." }, + BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." }, FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature:
function Callback({{cPlayer|cPlayer}})
" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature:
function Callback({{cWorld|cWorld}})
" }, @@ -2014,8 +2025,14 @@ end Functions = { + AreCommandBlocksEnabled = { Params = "", Return = "bool", Notes = "Returns whether command blocks are enabled on the (entire) server" }, BroadcastBlockAction = { Params = "BlockX, BlockY, BlockZ, ActionByte1, ActionByte2, BlockType, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Broadcasts the BlockAction packet to all clients who have the appropriate chunk loaded (except ExcludeClient). The contents of the packet are specified by the parameters for the call, the blocktype needn't match the actual block that is present in the world data at the specified location." }, - BroadcastChat = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Sends the Message to all players in this world, except the optional ExceptClient" }, + BroadcastChat = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Sends the Message to all players in this world, except the optional ExcludeClient. No formatting is done by the server." }, + BroadcastChatFailure = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a command that failed to run because of insufficient permissions, etc." }, + BroadcastChatFatal = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a plugin that crashed, or similar." }, + BroadcastChatInfo = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." }, + BroadcastChatSuccess = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." }, + BroadcastChatWarning = { Params = "Message, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." }, BroadcastSoundEffect = { Params = "SoundName, X, Y, Z, Volume, Pitch, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Sends the specified sound effect to all players in this world, except the optional ExceptClient" }, BroadcastSoundParticleEffect = { Params = "EffectID, X, Y, Z, EffectData, [{{cClientHandle|ExcludeClient}}]", Return = "", Notes = "Sends the specified effect to all players in this world, except the optional ExceptClient" }, CastThunderbolt = { Params = "X, Y, Z", Return = "", Notes = "Creates a thunderbolt at the specified coords" }, @@ -2111,6 +2128,10 @@ end { Params = "{{Vector3i|BlockCoords}}, BlockMeta", Return = "", Notes = "Sets the meta for the block at the specified coords." }, }, SetNextBlockTick = { Params = "BlockX, BlockY, BlockZ", Return = "", Notes = "Sets the blockticking to start at the specified block in the next tick." }, + SetCommandBlockCommand = { Params = "BlockX, BlockY, BlockZ, Command", Return = "bool", Notes = "Sets the command to be executed in a command block at the specified coordinates. Returns if command was changed." }, + SetCommandBlocksEnabled = { Params = "IsEnabled (bool)", Return = "", Notes = "Sets whether command blocks should be enabled on the (entire) server." }, + SetShouldUseChatPrefixes = { Params = "", Return = "ShouldUse (bool)", Notes = "Sets whether coloured chat prefixes such as [INFO] is used with the SendMessageXXX() or BroadcastChatXXX(), or simply the entire message is coloured in the respective colour." }, + ShouldUseChatPrefixes = { Params = "", Return = "bool", Notes = "Returns whether coloured chat prefixes are prepended to chat messages or the entire message is simply coloured." }, SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as UpdateSign()." }, SetTicksUntilWeatherChange = { Params = "NumTicks", Return = "", Notes = "Sets the number of ticks after which the weather will be changed." }, SetTimeOfDay = { Params = "TimeOfDayTicks", Return = "", Notes = "Sets the time of day, expressed as number of ticks past sunrise, in the range 0 .. 24000." }, diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f7c6cb734..911c0795f 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -566,7 +566,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a { if (a_Length < 14) { - SendChat(AppendChatEpithet("Failure setting command block command; bad request", mtFailure)); + SendChat("Failure setting command block command; bad request", mtFailure); LOGD("Malformed MC|AdvCdm packet."); return; } @@ -596,7 +596,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a default: { - SendChat(AppendChatEpithet("Failure setting command block command; unhandled mode", mtFailure)); + SendChat("Failure setting command block command; unhandled mode", mtFailure); LOGD("Unhandled MC|AdvCdm packet mode."); return; } @@ -608,11 +608,11 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a { World->SetCommandBlockCommand(BlockX, BlockY, BlockZ, Command); - SendChat(AppendChatEpithet("Successfully set command block command", mtSuccess)); + SendChat("Successfully set command block command", mtSuccess); } else { - SendChat(AppendChatEpithet("Command blocks are not enabled on this server", mtFailure)); + SendChat("Command blocks are not enabled on this server", mtFailure); } } @@ -1729,9 +1729,111 @@ void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlock -void cClientHandle::SendChat(const AString & a_Message) +void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData) { - m_Protocol->SendChat(a_Message); + bool ShouldAppendChatPrefixes = true; + + if (GetPlayer()->GetWorld() == NULL) + { + cWorld * 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; + + switch (a_ChatPrefix) + { + case mtCustom: break; + case mtFailure: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Rose.c_str()); + break; + } + case mtInformation: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Yellow.c_str()); + break; + } + case mtSuccess: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Green.c_str()); + break; + } + case mtWarning: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Rose.c_str()); + break; + } + case mtFatal: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Red.c_str()); + break; + } + case mtDeath: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Gray.c_str()); + break; + } + case mtPrivateMessage: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[MSG: %s] %s%s", cChatColor::LightBlue.c_str(), a_AdditionalData.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str()); + else + Message = Printf("%s", cChatColor::LightBlue.c_str()); + break; + } + case mtJoin: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[JOIN] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Yellow.c_str()); + break; + } + case mtLeave: + { + if (ShouldAppendChatPrefixes) + Message = Printf("%s[LEAVE] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); + else + Message = Printf("%s", cChatColor::Yellow.c_str()); + break; + } + default: ASSERT(!"Unhandled chat prefix type!"); return; + } + + Message.append(a_Message); + + m_Protocol->SendChat(Message); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 29a56f5a7..c35289340 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -89,7 +89,7 @@ public: 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); + void SendChat (const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData = ""); void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer); void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player); void SendDestroyEntity (const cEntity & a_Entity); diff --git a/src/Defines.h b/src/Defines.h index 7fe93399d..177acefdf 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -448,6 +448,7 @@ enum ChatPrefixCodes // http://forum.mc-server.org/showthread.php?tid=1212 // MessageType... + mtCustom, // Send raw data without any processing mtFailure, // Something could not be done (i.e. command not executed due to insufficient privilege) mtInformation, // Informational message (i.e. command usage) mtSuccess, // Something executed successfully @@ -459,70 +460,9 @@ enum ChatPrefixCodes mtLeave, // A player has left the server }; - - - -inline AString AppendChatEpithet(const AString & a_ChatMessage, ChatPrefixCodes a_ChatPrefix) -{ - AString Message; - - switch (a_ChatPrefix) - { - case mtFailure: - { - Message = Printf("%s[INFO] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); - break; - } - case mtInformation: - { - Message = Printf("%s[INFO] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); - break; - } - case mtSuccess: - { - Message = Printf("%s[INFO] %s", cChatColor::Green.c_str(), cChatColor::White.c_str()); - break; - } - case mtWarning: - { - Message = Printf("%s[WARN] %s", cChatColor::Rose.c_str(), cChatColor::White.c_str()); - break; - } - case mtFatal: - { - Message = Printf("%s[FATAL] %s", cChatColor::Red.c_str(), cChatColor::White.c_str()); - break; - } - case mtDeath: - { - Message = Printf("%s[DEATH] %s", cChatColor::Gray.c_str(), cChatColor::White.c_str()); - break; - } - case mtPrivateMessage: - { - Message = Printf("%s[MSG] %s%s", cChatColor::LightBlue.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str()); - break; - } - case mtJoin: - { - Message = Printf("%s[JOIN] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); - break; - } - case mtLeave: - { - Message = Printf("%s[LEAVE] %s", cChatColor::Yellow.c_str(), cChatColor::White.c_str()); - break; - } - default: ASSERT(!"Unhandled chat prefix type!"); return ""; - } - - Message.append(a_ChatMessage); - return Message; -} - // tolua_begin -/// Normalizes an angle in degrees to the [-180, +180) range: +/** Normalizes an angle in degrees to the [-180, +180) range: */ inline double NormalizeAngleDegrees(const double a_Degrees) { double Norm = fmod(a_Degrees + 180, 360); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 385e28c28..eef6b8e69 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -3,7 +3,6 @@ #include "Player.h" #include "../Server.h" -#include "../ClientHandle.h" #include "../UI/Window.h" #include "../UI/WindowOwner.h" #include "../World.h" @@ -1121,15 +1120,6 @@ void cPlayer::SetIP(const AString & a_IP) -void cPlayer::SendMessage(const AString & a_Message) -{ - m_ClientHandle->SendChat(a_Message); -} - - - - - void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) { SetPosition( a_PosX, a_PosY, a_PosZ ); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index f2830a0c7..869e67775 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -5,6 +5,7 @@ #include "../Inventory.h" #include "../Defines.h" #include "../World.h" +#include "../ClientHandle.h" @@ -195,13 +196,13 @@ public: cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } - void SendMessage(const AString & a_Message); - void SendMessageInfo(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtInformation)); } - void SendMessageFailure(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } - void SendMessageSuccess(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtSuccess)); } - void SendMessageWarning(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtWarning)); } - void SendMessageFatal(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtFailure)); } - void SendMessagePrivateMsg(const AString & a_Message) { SendMessage(AppendChatEpithet(a_Message, mtPrivateMessage)); } + void SendMessage (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtCustom); } + void SendMessageInfo (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtInformation); } + void SendMessageFailure (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); } + void SendMessageSuccess (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtSuccess); } + void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); } + void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); } + void SendMessagePrivateMsg(const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); } const AString & GetName(void) const { return m_PlayerName; } void SetName(const AString & a_Name) { m_PlayerName = a_Name; } diff --git a/src/Root.cpp b/src/Root.cpp index 883bfe76e..3e1898c42 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -536,11 +536,11 @@ void cRoot::SaveAllChunks(void) -void cRoot::BroadcastChat(const AString & a_Message) +void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix) { for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr) { - itr->second->BroadcastChat(a_Message); + itr->second->LoopPlayersAndBroadcastChat(a_Message, a_ChatPrefix); } // for itr - m_WorldsByName[] } diff --git a/src/Root.h b/src/Root.h index ba106b54e..4cb77a79d 100644 --- a/src/Root.h +++ b/src/Root.h @@ -105,19 +105,20 @@ public: /// Finds a player from a partial or complete player name and calls the callback - case-insensitive bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - void BroadcastChatJoin(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtJoin)); } - void BroadcastChatLeave(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtLeave)); } + void LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix); + void BroadcastChatJoin (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtJoin); } + void BroadcastChatLeave (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtLeave); } + void BroadcastChatDeath (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtDeath); } // tolua_begin /// Sends a chat message to all connected clients (in all worlds) - void BroadcastChat(const AString & a_Message); - void BroadcastChatInfo(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtInformation)); } - void BroadcastChatFailure(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } - void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtSuccess)); } - void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtWarning)); } - void BroadcastChatFatal(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } - void BroadcastChatDeath(const AString & a_Message) { BroadcastChat(AppendChatEpithet(a_Message, mtDeath)); } + void BroadcastChat (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtCustom); } + void BroadcastChatInfo (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtInformation); } + void BroadcastChatFailure(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); } + void BroadcastChatSuccess(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtSuccess); } + void BroadcastChatWarning(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtWarning); } + void BroadcastChatFatal (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); } /// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum); diff --git a/src/World.cpp b/src/World.cpp index de2002b84..e5c9f4398 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -249,7 +249,9 @@ cWorld::cWorld(const AString & a_WorldName) : m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) m_GeneratorCallbacks(*this), m_TickThread(*this), - m_Scoreboard(this) + m_Scoreboard(this), + m_bCommandBlocksEnabled(false), + m_bUseChatPrefixes(true) { LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); @@ -543,9 +545,10 @@ void cWorld::Start(void) m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true); - m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false); + m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); + m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); @@ -1744,7 +1747,7 @@ void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons -void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude) +void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -1754,7 +1757,7 @@ void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Ex { continue; } - ch->SendChat(a_Message); + ch->SendChat(a_Message, a_ChatPrefix); } } diff --git a/src/World.h b/src/World.h index 01481c049..0527abbff 100644 --- a/src/World.h +++ b/src/World.h @@ -158,14 +158,16 @@ public: void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude - // tolua_start - void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); - void BroadcastChatInfo(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtInformation)); } - void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } - void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtSuccess)); } - void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtWarning)); } - void BroadcastChatFatal(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtFailure)); } - void BroadcastChatDeath(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(AppendChatEpithet(a_Message, mtDeath)); } + void LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude = NULL); + void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtDeath, a_Exclude); } + + // tolua_begin + void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtCustom, a_Exclude); } + void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtInformation, a_Exclude); } + void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); } + void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtSuccess, a_Exclude); } + void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtWarning, a_Exclude); } + void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); } // tolua_end void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); @@ -544,12 +546,14 @@ public: /** Returns the name of the world.ini file used by this world */ const AString & GetIniFileName(void) const {return m_IniFileName; } - /// Returns the associated scoreboard instance + /** Returns the associated scoreboard instance */ cScoreboard & GetScoreBoard(void) { return m_Scoreboard; } bool AreCommandBlocksEnabled(void) const { return m_bCommandBlocksEnabled; } - void SetCommandBlocksEnabled(bool a_Flag) { m_bCommandBlocksEnabled = a_Flag; } + + bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } + void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } // tolua_end @@ -800,7 +804,10 @@ private: bool m_IsSaplingBonemealable; bool m_IsSugarcaneBonemealable; + /** Whether command blocks are enabled or not */ bool m_bCommandBlocksEnabled; + /** Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions */ + bool m_bUseChatPrefixes; cChunkGenerator m_Generator; -- cgit v1.2.3 From 0a5c14bf68439d450bc94ec9da63f4e424a75d95 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 7 Feb 2014 19:56:22 +0000 Subject: Removed some unexported documentation. --- MCServer/Plugins/APIDump/APIDesc.lua | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 69e1bdda9..2f0feac7f 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -693,7 +693,6 @@ end GetRawDamageAgainst = { Params = "ReceiverEntity", Return = "number", Notes = "Returns the raw damage that this entity's equipment would cause when attacking the ReceiverEntity. This includes this entity's weapon {{cEnchantments|enchantments}}, but excludes the receiver's armor or potion effects. See {{TakeDamageInfo}} for more information on attack damage." }, GetRoll = { Params = "", Return = "number", Notes = "Returns the roll (sideways rotation) of the entity. Currently unused." }, GetRot = { Params = "", Return = "{{Vector3f}}", Notes = "Returns the entire rotation vector (Yaw, Pitch, Roll)" }, - GetRotation = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. OBSOLETE, use GetYaw() instead." }, GetSpeed = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the complete speed vector of the entity" }, GetSpeedX = { Params = "", Return = "number", Notes = "Returns the X-part of the speed vector" }, GetSpeedY = { Params = "", Return = "number", Notes = "Returns the Y-part of the speed vector" }, @@ -720,8 +719,11 @@ end IsRclking = { Params = "", Return = "bool", Notes = "Currently unimplemented" }, IsRiding = { Params = "", Return = "bool", Notes = "Returns true if the entity is attached to (riding) another entity." }, IsSprinting = { Params = "", Return = "bool", Notes = "Returns true if the entity is sprinting. Entities that cannot sprint return always false" }, + IsSubmerged = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is submerged in water (head is in a water block). Note, this function is only updated with mobs or players." }, + IsSwimming = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is swimming in water (feet are in a water block). Note, this function is only updated with mobs or players." }, IsTNT = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cTNTEntity|TNT entity}}" }, KilledBy = { Notes = "FIXME: Remove this from API" }, + GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left). Note, this function is only updated with mobs or players." }, SetGravity = { Params = "Gravity", Return = "", Notes = "Sets the number that is used as the gravity for physics simulation. 1G (9.78) by default." }, SetHeadYaw = { Params = "HeadPitch", Return = "", Notes = "Sets the head pitch (FIXME: Rename to SetHeadPitch() )." }, SetHealth = { Params = "Hitpoints", Return = "", Notes = "Sets the entity's health to the specified amount of hitpoints. Doesn't broadcast any hurt animation. Doesn't kill the entity if health drops below zero. Use the TakeDamage() function instead for taking damage." }, @@ -740,8 +742,7 @@ end SetPosZ = { Params = "number", Return = "", Notes = "Sets the Z-coord of the entity's pivot" }, SetRoll = { Params = "number", Return = "", Notes = "Sets the roll (sideways rotation) of the entity. Currently unused." }, SetRot = { Params = "{{Vector3f|Rotation}}", Return = "", Notes = "Sets the entire rotation vector (Yaw, Pitch, Roll)" }, - SetRotation = { Params = "number", Return = "", Notes = "Sets the yaw (direction) of the entity. OBSOLETE, use SetYaw() instead." }, - SetRotationFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves). (FIXME: Rename to SetYawFromSpeed)" }, + SetYawFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves). (FIXME: Rename to SetYawFromSpeed)" }, SetSpeed = { { Params = "SpeedX, SpeedY, SpeedZ", Return = "", Notes = "Sets the current speed of the entity" }, @@ -1103,10 +1104,9 @@ These ItemGrids are available in the API and can be manipulated by the plugins, GetMaxStackSize = { Params = "", Return = "number", Notes = "Returns the maximum stack size for this item." }, IsDamageable = { Params = "", Return = "bool", Notes = "Returns true if this item does account for its damage" }, IsEmpty = { Params = "", Return = "bool", Notes = "Returns true if this object represents an empty item (zero count or invalid ID)" }, - IsEqual = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is the same as the one stored in the object (type, damage and enchantments)" }, + IsEqual = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is the same as the one stored in the object (type, damage, lore, name and enchantments)" }, IsFullStack = { Params = "", Return = "bool", Notes = "Returns true if the item is stacked up to its maximum stacking" }, IsSameType = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is of the same ItemType as the one stored in the object. This is true even if the two items have different enchantments" }, - IsStackableWith = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is stackable with the one stored in the object. Two items with different enchantments cannot be stacked" }, }, Variables = { @@ -1564,7 +1564,6 @@ a_Player:OpenWindow(Window); ]], Functions = { - constructor = { Params = "PosX, PosY, PosZ, {{cItem|Item}}, IsPlayerCreated, [SpeedX, SpeedY, SpeedZ]", Return = "cPickup", Notes = "Creates a new pickup at the specified coords. If IsPlayerCreated is true, the pickup has a longer initial collection interval." }, CollectedBy = { Params = "{{cPlayer}}", Return = "bool", Notes = "Tries to make the player collect the pickup. Returns true if the pickup was collected, at least partially." }, GetAge = { Params = "", Return = "number", Notes = "Returns the number of ticks that the pickup has existed." }, GetItem = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item represented by this pickup" }, @@ -1594,7 +1593,6 @@ a_Player:OpenWindow(Window); Feed = { Params = "AddFood, AddSaturation", Return = "bool", Notes = "Tries to add the specified amounts to food level and food saturation level (only positive amounts expected). Returns true if player was hungry and the food was consumed, false if too satiated." }, FoodPoison = { Params = "NumTicks", Return = "", Notes = "Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two" }, ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." }, - GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left)." }, GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." }, GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." }, GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" }, @@ -1635,8 +1633,6 @@ a_Player:OpenWindow(Window); IsInGroup = { Params = "GroupNameString", Return = "bool", Notes = "Returns true if the player is a member of the specified group." }, IsOnGround = { Params = "", Return = "bool", Notes = "Returns true if the player is on ground (not falling, not jumping, not flying)" }, IsSatiated = { Params = "", Return = "bool", Notes = "Returns true if the player is satiated (cannot eat)." }, - IsSubmerged = { Params = "", Return = "bool", Notes = "Returns true if the player is submerged in water (the player's head is in a water block)" }, - IsSwimming = { Params = "", Return = "bool", Notes = "Returns true if the player is swimming in water (the player's feet are in a water block)" }, IsVisible = { Params = "", Return = "bool", Notes = "Returns true if the player is visible to other players" }, LoadPermissionsFromDisk = { Params = "", Return = "", Notes = "Reloads the player's permissions from the disk. This loses any temporary changes made to the player's groups." }, MoveTo = { Params = "{{Vector3d|NewPosition}}", Return = "Tries to move the player into the specified position." }, @@ -1672,9 +1668,7 @@ a_Player:OpenWindow(Window); }, Constants = { - DROWNING_TICKS = { Notes = "Number of ticks per heart of damage when drowning (zero AirLevel)" }, EATING_TICKS = { Notes = "Number of ticks required for consuming an item." }, - MAX_AIR_LEVEL = { Notes = "The maximum air level value. AirLevel gets reset to this value when the player exits water." }, MAX_FOOD_LEVEL = { Notes = "The maximum food level value. When the food level is at this value, the player cannot eat." }, MAX_HEALTH = { Notes = "The maximum health value" }, }, -- cgit v1.2.3 From 0f36d1c122c78757c9106eb6afa5e3897a87e5fb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 7 Feb 2014 20:10:12 +0000 Subject: Added sender name to PM if prefixes disabled * Also moved the PVP setting into Mechanics --- src/ClientHandle.cpp | 2 +- src/World.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 911c0795f..15b614999 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1809,7 +1809,7 @@ void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPr if (ShouldAppendChatPrefixes) Message = Printf("%s[MSG: %s] %s%s", cChatColor::LightBlue.c_str(), a_AdditionalData.c_str(), cChatColor::White.c_str(), cChatColor::Italic.c_str()); else - Message = Printf("%s", cChatColor::LightBlue.c_str()); + Message = Printf("%s: %s", a_AdditionalData.c_str(), cChatColor::LightBlue.c_str()); break; } case mtJoin: diff --git a/src/World.cpp b/src/World.cpp index e5c9f4398..bb6f5f29a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -544,10 +544,10 @@ void cWorld::Start(void) m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); - m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true); m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); + m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); -- cgit v1.2.3 From fadf3c037ba02e18264dabbad5f1016fa53a995d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 7 Feb 2014 20:11:56 +0000 Subject: Moved Gamemode setting into General root tag --- src/World.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index bb6f5f29a..ab77fa545 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -551,7 +551,7 @@ void cWorld::Start(void) m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); - m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode); + m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode); // Load allowed mobs: const char * DefaultMonsters = ""; -- cgit v1.2.3 From 645c096e2b76c6a42a2b0c679553475d63054f75 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 9 Feb 2014 00:02:16 +0100 Subject: The console reload command also reloads the groups. --- src/Server.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Server.cpp b/src/Server.cpp index ba2b46d55..62b4442d2 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -459,6 +459,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); + cRoot::Get()->ReloadGroups(); return; } -- cgit v1.2.3 From 14b5054c95bc294a62792b4d82331c970809f07f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 8 Feb 2014 23:02:50 +0000 Subject: Fixed a boat ASSERT --- src/Entities/Boat.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 184aeeeeb..67df201ce 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -89,8 +89,14 @@ void cBoat::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); - SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed. - if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ()))) + SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed + + if ((POSY_TOINT < 0) || (POSY_TOINT > cChunkDef::Height)) + { + return; + } + + if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT))) { SetSpeedY(1); } -- cgit v1.2.3 From 011a334a8a1bf7a7efcfbbbe895ebae9432ce118 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 9 Feb 2014 00:06:37 +0100 Subject: Split "reload" in "reloadplugins" and "reloadgroups". --- src/Server.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Server.cpp b/src/Server.cpp index 62b4442d2..671d251cd 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -456,12 +456,15 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac PrintHelp(split, a_Output); return; } - if (split[0] == "reload") + if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); - cRoot::Get()->ReloadGroups(); return; } + if (split[0] == "reloadgroups") + { + cRoot::Get()->ReloadGroups(); + } // There is currently no way a plugin can do these (and probably won't ever be): if (split[0].compare("chunkstats") == 0) -- cgit v1.2.3 From 2a741e719cd827344bc441a04b27f3e3c8493d33 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 9 Feb 2014 00:13:25 +0100 Subject: "reload" is back. --- src/Server.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Server.cpp b/src/Server.cpp index 671d251cd..ab1458da4 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -456,6 +456,12 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac PrintHelp(split, a_Output); return; } + if (split[0] == "reload") + { + cPluginManager::Get()->ReloadPlugins(); + cRoot::Get()->ReloadGroups(); + return; + } if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); @@ -464,6 +470,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac if (split[0] == "reloadgroups") { cRoot::Get()->ReloadGroups(); + return; } // There is currently no way a plugin can do these (and probably won't ever be): -- cgit v1.2.3 From c68bdaf34beee368100e6697fc3d87a711dba6b7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Feb 2014 00:57:22 +0000 Subject: Fixed compile and some warnings in MSVS --- src/Blocks/BlockButton.h | 2 +- src/Blocks/BlockLever.h | 2 +- src/Blocks/BlockTrapdoor.h | 2 +- src/Generating/StructGen.cpp | 9 --------- src/MobSpawner.cpp | 2 +- src/World.cpp | 2 -- src/WorldStorage/ScoreboardSerializer.cpp | 4 ++-- 7 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index f2a2885be..ca6850ced 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -88,7 +88,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return 0; + return BLOCK_FACE_NONE; } } } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 8b4126873..48c7e774b 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -88,7 +88,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return 0; + return BLOCK_FACE_NONE; } } } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 47b51db16..08fc28327 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -84,7 +84,7 @@ public: default: { ASSERT(!"Unhandled block meta!"); - return 0; + return BLOCK_FACE_NONE; } } } diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index da6227801..4efcf92f0 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -60,15 +60,6 @@ template T Clamp(T a_Value, T a_Min, T a_Max) -static bool SortTreeBlocks(const sSetBlock & a_First, const sSetBlock & a_Second) -{ - return (a_First.BlockType == E_BLOCK_LOG) && (a_Second.BlockType != E_BLOCK_LOG); -} - - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenTrees: diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 4d0b2777b..c86268e63 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -126,7 +126,7 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome) bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, cMonster::eType a_MobType, EMCSBiome a_Biome) { - BLOCKTYPE TargetBlock; + BLOCKTYPE TargetBlock = E_BLOCK_AIR; if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { NIBBLETYPE BlockLight = a_Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ); diff --git a/src/World.cpp b/src/World.cpp index d2523b0a5..662a9a4b8 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -251,10 +251,8 @@ cWorld::cWorld(const AString & a_WorldName) : m_Scoreboard(this), m_GeneratorCallbacks(*this), m_TickThread(*this), - m_Scoreboard(this), m_bCommandBlocksEnabled(false), m_bUseChatPrefixes(true) - m_TickThread(*this) { LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index c65e13f98..9b8b661c4 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -242,7 +242,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name, ObjectiveName; - cObjective::Score Score; + cObjective::Score Score = 0; int CurrLine = a_NBT.FindChildByName(Child, "Score"); if (CurrLine >= 0) @@ -280,7 +280,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name, DisplayName, Prefix, Suffix; - bool AllowsFriendlyFire, CanSeeFriendlyInvisible; + bool AllowsFriendlyFire = false, CanSeeFriendlyInvisible = false; int CurrLine = a_NBT.FindChildByName(Child, "Name"); if (CurrLine >= 0) -- cgit v1.2.3 From 373e450518ea17e2615fadaafd1d5d52e8d60f1a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Feb 2014 01:04:16 +0000 Subject: Updated Core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 5fe3662a8..7f97e93ef 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 5fe3662a8719f79cb2ca0a16150c716a3c5eb19c +Subproject commit 7f97e93ef25616673e8342b7919d9b5914e1327e -- cgit v1.2.3