summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Bindings/PluginManager.cpp4
-rw-r--r--src/Blocks/BlockBed.cpp2
-rw-r--r--src/Blocks/BlockCrops.h2
-rw-r--r--src/Blocks/BlockFarmland.h2
-rw-r--r--src/Blocks/BlockTrapdoor.h2
-rw-r--r--src/ChunkMap.cpp2
-rw-r--r--src/ClientHandle.cpp172
-rw-r--r--src/ClientHandle.h15
-rw-r--r--src/Defines.h21
-rw-r--r--src/Entities/Boat.cpp10
-rw-r--r--src/Entities/ExpOrb.h1
-rw-r--r--src/Entities/Floater.h4
-rw-r--r--src/Entities/Pickup.h7
-rw-r--r--src/Entities/Player.cpp41
-rw-r--r--src/Entities/Player.h12
-rw-r--r--src/Generating/StructGen.cpp9
-rw-r--r--src/Items/ItemFood.h6
-rw-r--r--src/Items/ItemHandler.cpp25
-rw-r--r--src/Items/ItemSeeds.h20
-rw-r--r--src/MobSpawner.cpp2
-rw-r--r--src/Mobs/Monster.cpp2
-rw-r--r--src/OSSupport/File.cpp16
-rw-r--r--src/Protocol/Protocol17x.cpp3
-rw-r--r--src/Root.cpp4
-rw-r--r--src/Root.h17
-rw-r--r--src/Server.cpp11
-rw-r--r--src/World.cpp15
-rw-r--r--src/World.h23
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp1
-rw-r--r--src/WorldStorage/ScoreboardSerializer.cpp4
30 files changed, 328 insertions, 127 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 2fd993817..a6f3c36b6 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/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:
{
diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h
index 37e79a1e1..08fc28327 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;
}
}
}
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index a9f6bf00b..7726a0b7e 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -1847,7 +1847,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), 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 aa43f192c..1b3ebc3d4 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 20
-/// 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)
{
@@ -227,7 +223,11 @@ void cClientHandle::Authenticate(void)
m_Player->SetIP (m_IPString);
- cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player);
+ if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player))
+ {
+ cRoot::Get()->BroadcastChatJoin(Printf("%s has joined the game", GetUsername().c_str()));
+ LOGINFO("Player %s has joined the game.", m_Username.c_str());
+ }
m_ConfirmPosition = m_Player->GetPosition();
@@ -566,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("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(Printf("%s[INFO]%s Failure setting command block command; unhandled mode", cChatColor::Red.c_str(), cChatColor::White.c_str()));
+ SendChat("Failure setting command block command; unhandled mode", mtFailure);
LOGD("Unhandled MC|AdvCdm packet mode.");
return;
}
@@ -607,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("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("Command blocks are not enabled on this server", mtFailure);
}
}
@@ -910,7 +910,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
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 +1330,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();
}
@@ -1635,10 +1631,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;
}
@@ -1735,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: %s", a_AdditionalData.c_str(), 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);
}
@@ -1918,18 +2014,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);
}
@@ -2459,13 +2551,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/ClientHandle.h b/src/ClientHandle.h
index a4a22e4df..d9a86d983 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();
@@ -92,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);
@@ -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;
diff --git a/src/Defines.h b/src/Defines.h
index 1a12a8743..290f862ef 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -1,6 +1,8 @@
#pragma once
+#include "ChatColor.h"
+
@@ -439,9 +441,26 @@ inline float GetSpecialSignf( float a_Val )
+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
+ 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
+ mtJoin, // A player has joined the server
+ mtLeave, // A player has left the server
+};
+
// 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/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);
}
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;
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index bea8def9e..286d43cf6 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"
@@ -130,9 +129,13 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
cPlayer::~cPlayer(void)
{
- cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this);
+ if (!cRoot::Get()->GetPluginManager()->CallHookPlayerDestroyed(*this))
+ {
+ cRoot::Get()->BroadcastChatLeave(Printf("%s has left the game", GetName().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);
@@ -841,18 +844,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
@@ -1117,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 );
@@ -1741,6 +1735,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 5c56c927a..7db9544cb 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,7 +196,13 @@ public:
cClientHandle * GetClientHandle(void) const { return m_ClientHandle; }
- void SendMessage(const AString & a_Message);
+ 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; }
@@ -467,6 +474,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);
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 <typename T> 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/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 f7115c558..19913ab24 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 ba3b2538b..7283edcee 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,
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/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index be901ac61..ad3a87725 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -276,7 +276,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/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);
}
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 57da48e49..7eaf106cf 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
diff --git a/src/Root.cpp b/src/Root.cpp
index 0bd2b58fe..749fbd288 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -543,11 +543,11 @@ void cRoot::ReloadGroups(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 71ee2e671..13e208b8d 100644
--- a/src/Root.h
+++ b/src/Root.h
@@ -3,6 +3,7 @@
#include "Authenticator.h"
#include "HTTPServer/HTTPServer.h"
+#include "Defines.h"
@@ -100,18 +101,28 @@ public:
/// Reloads all the groups
void ReloadGroups(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 <<
/// 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 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) { 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/Server.cpp b/src/Server.cpp
index ba2b46d55..ab1458da4 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -459,6 +459,17 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
if (split[0] == "reload")
{
cPluginManager::Get()->ReloadPlugins();
+ cRoot::Get()->ReloadGroups();
+ return;
+ }
+ if (split[0] == "reloadplugins")
+ {
+ cPluginManager::Get()->ReloadPlugins();
+ return;
+ }
+ if (split[0] == "reloadgroups")
+ {
+ cRoot::Get()->ReloadGroups();
return;
}
diff --git a/src/World.cpp b/src/World.cpp
index dfc186639..c2149e4c0 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -250,7 +250,9 @@ cWorld::cWorld(const AString & a_WorldName) :
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
m_Scoreboard(this),
m_GeneratorCallbacks(*this),
- m_TickThread(*this)
+ m_TickThread(*this),
+ m_bCommandBlocksEnabled(false),
+ m_bUseChatPrefixes(true)
{
LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
@@ -543,13 +545,14 @@ 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", false);
+ 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);
- m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode);
+ m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode);
// Load allowed mobs:
const char * DefaultMonsters = "";
@@ -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 b82bdc67c..26f3993e0 100644
--- a/src/World.h
+++ b/src/World.h
@@ -157,7 +157,19 @@ 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
+
+ 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);
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);
@@ -531,12 +543,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
@@ -787,7 +801,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;
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:
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)