1
0
Fork 0

Merge branch 'master' into chunksparsing/structs

Conflicts:
	src/Chunk.cpp
This commit is contained in:
Tycho 2014-05-03 06:07:56 -07:00
commit ec407dd27d
36 changed files with 198 additions and 92 deletions

View File

@ -45,7 +45,30 @@ It is possible to use an external profiler to learn more about how the code perf
There's a script file, `MCServer/profile_run.cmd` that encapsulates most of the profiling work, have a look at the comments at the top of that script for details on how to get it to work. You'll need to change to a profiled configuration (both debug and release can be profiled).
## Linux, MacOS, FreeBSD etc. ##
## OSX ##
Install git from its [website](http://git-scm.com) or homebrew: `brew install git`.
Install Xcode (commandline tools are recommended) from the App Store or https://developer.apple.com/downloads.
Install CMake from its [website](http://cmake.org) or homebrew: `brew install cmake`.
### Getting the sources ###
```
mkdir MCServer
cd MCServer
git clone https://github.com/mc-server/MCServer.git .
git submodule init
git submodule update
```
### Building ###
Follow the instructions at [CMake on Unix-based platforms](#cmake-on-unix-based-platforms), using Xcode as cmake's generator. If no generator is specified, CMake will use the Makefile generator, in which case you must build with the `make` command.
After doing so, run the command `xcodebuild lib/polarssl/POLARSSL.xcodeproj` in the build directory, in order to build polarssl, a library that is required by MCServer. Lastly, run the command `xcodebuild` to build MCServer. Optionally, you may open the project files for polarssl and then MCServer in Xcode and build there.
## Linux, FreeBSD etc. ##
Install git, cmake and gcc or clang, using your platform's package manager:
```
@ -61,6 +84,14 @@ git submodule init
git submodule update
```
### Building ###
Follow the instructions at [CMake on Unix-based platforms](#cmake-on-unix-based-platforms).
After doing so, run the command `make` in the build directory, and MCServer will build.
## CMake on Unix-based platforms ###
### Release Mode ###
Release mode is preferred for almost all cases, it has much better speed and less console spam. However, if you are developing MCServer actively, debug mode might be better.
@ -69,8 +100,10 @@ Assuming you are in the MCServer folder created in the initial setup step, you n
```
mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=RELEASE .. && make
cmake -DCMAKE_BUILD_TYPE=RELEASE ..
```
NOTE: CMake can generate project files for many different programs, such as Xcode, eclipse, and ninja. To use a different generator, first type `cmake --help`, and at the end, cmake will output the different generators that are available. To specify one, add `-G` followed by the name of the generator, in the `cmake` command. Note that the name is case-sensitive.
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer`.
### Debug Mode ###
@ -81,8 +114,10 @@ Assuming you are in the MCServer folder created in the Getting the sources step,
```
mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=DEBUG .. && make
cmake -DCMAKE_BUILD_TYPE=DEBUG ..
```
NOTE: CMake can generate project files for many different programs, such as Xcode, eclipse, and ninja. To use a different generator, first type `cmake --help`, and at the end, cmake will output the different generators that are available. To specify one, add `-G` followed by the name of the generator, in the `cmake` command. Note that the name is case-sensitive.
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer_debug`.
### 32 Bit Mode switch ###

View File

@ -2,23 +2,33 @@ return
{
HOOK_DISCONNECT =
{
CalledWhen = "A player has explicitly disconnected.",
CalledWhen = [[
A client has disconnected, either by explicitly sending the disconnect packet (in older protocols) or
their connection was terminated
]],
DefaultFnName = "OnDisconnect", -- also used as pagename
Desc = [[
This hook is called when a client is about to be disconnected from the server, for whatever reason.
<p><b>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.</b></p>
This hook is called when a client has disconnected from the server, for whatever reason. It is also
called when the client sends the Disconnect packet (only in pre-1.7 protocols). This hook is not called
for server ping connections.</p>
<p>
Note that the hook is called even for connections to players who failed to auth. In such a case there's
no {{cPlayer}} object associated with the client.</p>
<p>
See also the {{OnHandshake|HOOK_HANDSHAKE}} hook which is called when the client connects (and presents
a handshake message, so that they are not just status-pinging). If you need to store a per-player
object, use the {{OnPlayerJoined|HOOK_PLAYER_JOINED}} and {{OnPlayerDestroyed|HOOK_PLAYER_DESTROYED}}
hooks instead, those are guaranteed to have the {{cPlayer}} object associated.
]],
Params =
{
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has disconnected" },
{ Name = "Client", Type = "{{cClientHandle}}", Notes = "The client who has disconnected" },
{ 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.
If the function returns true, no other plugins are called for this event. In either case,
the player is disconnected.
the client is disconnected.
]],
}, -- HOOK_DISCONNECT
}

View File

@ -27,10 +27,14 @@ local function LoadAPIFiles(a_Folder, a_DstTable)
-- We only want .lua files from the folder:
if (cFile:IsFile(FileName) and fnam:match(".*%.lua$")) then
local TablesFn, Err = loadfile(FileName);
if (TablesFn == nil) then
if (type(TablesFn) ~= "function") then
LOGWARNING("Cannot load API descriptions from " .. FileName .. ", Lua error '" .. Err .. "'.");
else
local Tables = TablesFn();
if (type(Tables) ~= "table") then
LOGWARNING("Cannot load API descriptions from " .. FileName .. ", returned object is not a table (" .. type(Tables) .. ").");
break
end
for k, cls in pairs(Tables) do
a_DstTable[k] = cls;
end

View File

@ -42,7 +42,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos)
// Add each set of coords:
int NumChunks = luaL_getn(L, a_ChunkCoordTableStackPos);
m_Chunks.reserve(NumChunks);
m_Chunks.reserve((size_t)NumChunks);
for (int idx = 1; idx <= NumChunks; idx++)
{
// Push the idx-th element of the array onto stack top, check that it's a table:

View File

@ -4,12 +4,12 @@
#include <time.h>
// tolua_begin
unsigned int GetTime()
inline unsigned int GetTime()
{
return (unsigned int)time(0);
}
std::string GetChar( std::string & a_Str, unsigned int a_Idx )
inline std::string GetChar( std::string & a_Str, unsigned int a_Idx )
{
return std::string(1, a_Str[ a_Idx ]);
}

View File

@ -37,7 +37,7 @@
/****************************
* Better error reporting for Lua
**/
int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
static int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
{
// Retrieve current function name
lua_Debug entry;
@ -57,7 +57,7 @@ int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaErro
int lua_do_error(lua_State* L, const char * a_pFormat, ...)
static int lua_do_error(lua_State* L, const char * a_pFormat, ...)
{
// Retrieve current function name
lua_Debug entry;
@ -235,7 +235,7 @@ static int tolua_Base64Decode(lua_State * tolua_S)
cPluginLua * GetLuaPlugin(lua_State * L)
static cPluginLua * GetLuaPlugin(lua_State * L)
{
// Get the plugin identification out of LuaState:
lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
@ -1776,20 +1776,20 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
static int tolua_cPlayer_GetGroups(lua_State * tolua_S)
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
const cPlayer::GroupList & AllGroups = self->GetGroups();
lua_createtable(tolua_S, AllGroups.size(), 0);
lua_createtable(tolua_S, (int)AllGroups.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cPlayer::GroupList::const_iterator iter = AllGroups.begin();
while(iter != AllGroups.end())
while (iter != AllGroups.end())
{
const cGroup* Group = *iter;
tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" );
const cGroup * Group = *iter;
tolua_pushusertype(tolua_S, (void *)Group, "const cGroup");
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
@ -1801,20 +1801,20 @@ static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S)
static int tolua_cPlayer_GetResolvedPermissions(lua_State * tolua_S)
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
cPlayer * self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
cPlayer::StringList AllPermissions = self->GetResolvedPermissions();
lua_createtable(tolua_S, AllPermissions.size(), 0);
lua_createtable(tolua_S, (int)AllPermissions.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cPlayer::StringList::iterator iter = AllPermissions.begin();
while(iter != AllPermissions.end())
while (iter != AllPermissions.end())
{
std::string& Permission = *iter;
tolua_pushstring( tolua_S, Permission.c_str() );
std::string & Permission = *iter;
lua_pushlstring(tolua_S, Permission.c_str(), Permission.length());
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
@ -2076,18 +2076,18 @@ static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S)
static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S)
{
cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S, 1, NULL);
cWebAdmin * self = (cWebAdmin *)tolua_tousertype(tolua_S, 1, NULL);
const cWebAdmin::PluginList & AllPlugins = self->GetPlugins();
lua_createtable(tolua_S, AllPlugins.size(), 0);
lua_createtable(tolua_S, (int)AllPlugins.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cWebAdmin::PluginList::const_iterator iter = AllPlugins.begin();
while(iter != AllPlugins.end())
while (iter != AllPlugins.end())
{
const cWebPlugin* Plugin = *iter;
tolua_pushusertype( tolua_S, (void*)Plugin, "const cWebPlugin" );
const cWebPlugin * Plugin = *iter;
tolua_pushusertype(tolua_S, (void *)Plugin, "const cWebPlugin");
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;

View File

@ -56,7 +56,7 @@ public:
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) = 0;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) = 0;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;

View File

@ -400,14 +400,14 @@ bool cPluginLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGri
bool cPluginLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason)
bool cPluginLua::OnDisconnect(cClientHandle & a_Client, const AString & a_Reason)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_DISCONNECT];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), a_Player, a_Reason, cLuaState::Return, res);
m_LuaState.Call((int)(**itr), &a_Client, a_Reason, cLuaState::Return, res);
if (res)
{
return true;

View File

@ -79,7 +79,7 @@ public:
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) override;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;

View File

@ -442,7 +442,7 @@ bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cC
bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Reason)
bool cPluginManager::CallHookDisconnect(cClientHandle & a_Client, const AString & a_Reason)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_DISCONNECT);
if (Plugins == m_Hooks.end())
@ -451,7 +451,7 @@ bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Re
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnDisconnect(a_Player, a_Reason))
if ((*itr)->OnDisconnect(a_Client, a_Reason))
{
return true;
}

View File

@ -172,7 +172,7 @@ public: // tolua_export
bool CallHookChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup);
bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);

View File

@ -1977,7 +1977,7 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
size_t BlockCount = (size_t)NewSizeX * NewSizeY * NewSizeZ;
size_t BlockCount = (size_t)(NewSizeX * NewSizeY * NewSizeZ);
BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount];
memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE));
int OldIndex = 0;
@ -2007,7 +2007,7 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
size_t BlockCount = (size_t)NewSizeX * NewSizeY * NewSizeZ;
size_t BlockCount = (size_t)(NewSizeX * NewSizeY * NewSizeZ);
NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount];
memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE));
int OldIndex = 0;

View File

@ -294,7 +294,7 @@ public:
NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block!
NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block!
NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block!
size_t GetBlockCount(void) const { return m_Size.x * m_Size.y * m_Size.z; }
size_t GetBlockCount(void) const { return (size_t)(m_Size.x * m_Size.y * m_Size.z); }
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const;
protected:

View File

@ -102,7 +102,7 @@ public:
return true;
}
a_Item.m_ItemDamage = atoi(Split[1].c_str());
a_Item.m_ItemDamage = (short)atoi(Split[1].c_str());
if ((a_Item.m_ItemDamage == 0) && (Split[1] != "0"))
{
// Parsing the number failed

View File

@ -327,7 +327,7 @@ bool cByteBuffer::ReadBEShort(short & a_Value)
CheckValid();
NEEDBYTES(2);
ReadBuf(&a_Value, 2);
a_Value = ntohs(a_Value);
a_Value = (short)ntohs((u_short)a_Value);
return true;
}
@ -341,7 +341,7 @@ bool cByteBuffer::ReadBEInt(int & a_Value)
CheckValid();
NEEDBYTES(4);
ReadBuf(&a_Value, 4);
a_Value = ntohl(a_Value);
a_Value = (int)ntohl((u_long)a_Value);
return true;
}
@ -420,7 +420,7 @@ bool cByteBuffer::ReadBEUTF16String16(AString & a_Value)
ASSERT(!"Negative string length? Are you sure?");
return true;
}
return ReadUTF16String(a_Value, Length);
return ReadUTF16String(a_Value, (size_t)Length);
}
@ -438,7 +438,7 @@ bool cByteBuffer::ReadVarInt(UInt32 & a_Value)
{
NEEDBYTES(1);
ReadBuf(&b, 1);
Value = Value | (((Int64)(b & 0x7f)) << Shift);
Value = Value | (((UInt32)(b & 0x7f)) << Shift);
Shift += 7;
} while ((b & 0x80) != 0);
a_Value = Value;
@ -462,7 +462,7 @@ bool cByteBuffer::ReadVarUTF8String(AString & a_Value)
{
LOGWARNING("%s: String too large: %u (%u KiB)", __FUNCTION__, Size, Size / 1024);
}
return ReadString(a_Value, (int)Size);
return ReadString(a_Value, (size_t)Size);
}
@ -517,7 +517,7 @@ bool cByteBuffer::WriteBEShort(short a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(2);
short Converted = htons(a_Value);
u_short Converted = htons((u_short)a_Value);
return WriteBuf(&Converted, 2);
}
@ -530,7 +530,7 @@ bool cByteBuffer::WriteBEInt(int a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(4);
int Converted = HostToNetwork4(&a_Value);
UInt32 Converted = HostToNetwork4(&a_Value);
return WriteBuf(&Converted, 4);
}
@ -543,7 +543,7 @@ bool cByteBuffer::WriteBEInt64(Int64 a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(8);
Int64 Converted = HostToNetwork8(&a_Value);
UInt64 Converted = HostToNetwork8(&a_Value);
return WriteBuf(&Converted, 8);
}
@ -556,7 +556,7 @@ bool cByteBuffer::WriteBEFloat(float a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(4);
int Converted = HostToNetwork4(&a_Value);
UInt32 Converted = HostToNetwork4(&a_Value);
return WriteBuf(&Converted, 4);
}
@ -569,7 +569,7 @@ bool cByteBuffer::WriteBEDouble(double a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(8);
Int64 Converted = HostToNetwork8(&a_Value);
UInt64 Converted = HostToNetwork8(&a_Value);
return WriteBuf(&Converted, 8);
}
@ -613,7 +613,7 @@ bool cByteBuffer::WriteVarInt(UInt32 a_Value)
// A 32-bit integer can be encoded by at most 5 bytes:
unsigned char b[5];
int idx = 0;
size_t idx = 0;
do
{
b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00);
@ -632,7 +632,7 @@ bool cByteBuffer::WriteVarUTF8String(const AString & a_Value)
CHECK_THREAD;
CheckValid();
PUTBYTES(a_Value.size() + 1); // This is a lower-bound on the bytes that will be actually written. Fail early.
bool res = WriteVarInt(a_Value.size());
bool res = WriteVarInt((UInt32)(a_Value.size()));
if (!res)
{
return false;
@ -757,7 +757,7 @@ bool cByteBuffer::ReadString(AString & a_String, size_t a_Count)
bool cByteBuffer::ReadUTF16String(AString & a_String, int a_NumChars)
bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars)
{
// Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String
CHECK_THREAD;

View File

@ -101,7 +101,7 @@ public:
bool ReadString(AString & a_String, size_t a_Count);
/// Reads 2 * a_NumChars bytes and interprets it as a UTF16-BE string, converting it into UTF8 string a_String
bool ReadUTF16String(AString & a_String, int a_NumChars);
bool ReadUTF16String(AString & a_String, size_t a_NumChars);
/// Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer
bool SkipRead(size_t a_Count);

View File

@ -716,7 +716,7 @@ void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList
void cClientHandle::HandleCommandBlockMessage(const char * a_Data, unsigned int a_Length)
void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Length)
{
if (a_Length < 14)
{
@ -1510,7 +1510,7 @@ void cClientHandle::HandleDisconnect(const AString & a_Reason)
{
LOGD("Received d/c packet from %s with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason);
cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, a_Reason);
m_HasSentDC = true;
Destroy();
@ -1658,7 +1658,7 @@ void cClientHandle::SendData(const char * a_Data, size_t a_Size)
{
// There is a queued overflow. Append to it, then send as much from its front as possible
m_OutgoingDataOverflow.append(a_Data, a_Size);
int CanFit = m_OutgoingData.GetFreeSpace();
size_t CanFit = m_OutgoingData.GetFreeSpace();
if (CanFit > 128)
{
// No point in moving the data over if it's not large enough - too much effort for too little an effect
@ -2689,9 +2689,9 @@ void cClientHandle::SocketClosed(void)
LOGD("Player %s @ %s disconnected", m_Username.c_str(), m_IPString.c_str());
if (m_Username != "") // Ignore client pings
if (!m_Username.empty()) // Ignore client pings
{
cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, "Player disconnected");
cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, "Player disconnected");
}
Destroy();

View File

@ -384,7 +384,7 @@ private:
void UnregisterPluginChannels(const AStringVector & a_ChannelList);
/** Handles the "MC|AdvCdm" plugin message */
void HandleCommandBlockMessage(const char * a_Data, unsigned int a_Length);
void HandleCommandBlockMessage(const char * a_Data, size_t a_Length);
// cSocketThreads::cCallback overrides:
virtual void DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client

View File

@ -73,6 +73,10 @@ public:
}
// The constructor is disabled in code, because the compiler generates it anyway,
// but it needs to stay because ToLua needs to generate the binding for it
#if 0
/** Creates an exact copy of the item */
cItem(const cItem & a_CopyFrom) :
m_ItemType (a_CopyFrom.m_ItemType),
@ -85,6 +89,8 @@ public:
{
}
#endif
void Empty(void)
{

View File

@ -33,7 +33,10 @@ public:
a_BlockY--;
}
if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, (cMonster::eType)(a_Item.m_ItemDamage)) >= 0)
cMonster::eType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage);
if (
(MonsterType != cMonster::mtInvalidType) && // Valid monster type
(a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) >= 0)) // Spawning succeeded
{
if (!a_Player->IsGameModeCreative())
{
@ -45,6 +48,41 @@ public:
return false;
}
/** Converts the Spawn egg item damage to the monster type to spawn.
Returns mtInvalidType for invalid damage values. */
static cMonster::eType ItemDamageToMonsterType(short a_ItemDamage)
{
switch (a_ItemDamage)
{
case E_META_SPAWN_EGG_BAT: return cMonster::mtBat;
case E_META_SPAWN_EGG_BLAZE: return cMonster::mtBlaze;
case E_META_SPAWN_EGG_CAVE_SPIDER: return cMonster::mtCaveSpider;
case E_META_SPAWN_EGG_CHICKEN: return cMonster::mtChicken;
case E_META_SPAWN_EGG_COW: return cMonster::mtCow;
case E_META_SPAWN_EGG_CREEPER: return cMonster::mtCreeper;
case E_META_SPAWN_EGG_ENDERMAN: return cMonster::mtEnderman;
case E_META_SPAWN_EGG_GHAST: return cMonster::mtGhast;
case E_META_SPAWN_EGG_HORSE: return cMonster::mtHorse;
case E_META_SPAWN_EGG_MAGMA_CUBE: return cMonster::mtMagmaCube;
case E_META_SPAWN_EGG_MOOSHROOM: return cMonster::mtMooshroom;
case E_META_SPAWN_EGG_OCELOT: return cMonster::mtOcelot;
case E_META_SPAWN_EGG_PIG: return cMonster::mtPig;
case E_META_SPAWN_EGG_SHEEP: return cMonster::mtSheep;
case E_META_SPAWN_EGG_SILVERFISH: return cMonster::mtSilverfish;
case E_META_SPAWN_EGG_SKELETON: return cMonster::mtSkeleton;
case E_META_SPAWN_EGG_SLIME: return cMonster::mtSlime;
case E_META_SPAWN_EGG_SPIDER: return cMonster::mtSpider;
case E_META_SPAWN_EGG_SQUID: return cMonster::mtSquid;
case E_META_SPAWN_EGG_VILLAGER: return cMonster::mtVillager;
case E_META_SPAWN_EGG_WITCH: return cMonster::mtWitch;
case E_META_SPAWN_EGG_WOLF: return cMonster::mtWolf;
case E_META_SPAWN_EGG_ZOMBIE: return cMonster::mtZombie;
case E_META_SPAWN_EGG_ZOMBIE_PIGMAN: return cMonster::mtZombiePigman;
}
return cMonster::mtInvalidType;
}
} ;

View File

@ -827,6 +827,10 @@ cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType)
switch (a_MobType)
{
case mtMagmaCube:
{
toReturn = new cMagmaCube(Random.NextInt(2) + 1);
break;
}
case mtSlime:
{
toReturn = new cSlime(Random.NextInt(2) + 1);

View File

@ -280,7 +280,7 @@ NOISE_DATATYPE cNoise::CubicInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B,
NOISE_DATATYPE cNoise::CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct)
{
const NOISE_DATATYPE ft = a_Pct * (NOISE_DATATYPE)3.1415927;
const NOISE_DATATYPE f = (1 - cos(ft)) * (NOISE_DATATYPE)0.5;
const NOISE_DATATYPE f = (NOISE_DATATYPE)((NOISE_DATATYPE)(1 - cos(ft)) * (NOISE_DATATYPE)0.5);
return a_A * (1 - f) + a_B * f;
}

View File

@ -75,7 +75,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
}
#ifdef _WIN32
fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), Mode);
m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), Mode, _SH_DENYWR);
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode);
#endif // _WIN32
@ -88,7 +88,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
// Simply re-open for read-writing, erasing existing contents:
#ifdef _WIN32
fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), "wb+");
m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+", _SH_DENYWR);
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+");
#endif // _WIN32

View File

@ -23,6 +23,9 @@ public:
class cDataCallbacks
{
public:
// Force a virtual destructor in descendants:
virtual ~cDataCallbacks() {}
/** Called when PolarSSL wants to read encrypted data from the SSL peer.
The returned value is the number of bytes received, or a PolarSSL error on failure.
The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate

View File

@ -123,7 +123,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) = 0;
virtual void SendWindowClose (const cWindow & a_Window) = 0;
virtual void SendWindowOpen (const cWindow & a_Window) = 0;
virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) = 0;
virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) = 0;
/// Returns the ServerID used for authentication through session.minecraft.net
virtual AString GetAuthServerID(void) = 0;

View File

@ -1175,7 +1175,7 @@ void cProtocol125::SendWindowOpen(const cWindow & a_Window)
void cProtocol125::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
void cProtocol125::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_WINDOW_PROPERTY);

View File

@ -96,7 +96,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (const cWindow & a_Window) override;
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override;
virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override;
virtual AString GetAuthServerID(void) override;

View File

@ -1383,7 +1383,7 @@ void cProtocol172::SendWindowOpen(const cWindow & a_Window)
void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
void cProtocol172::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value)
{
ASSERT(m_State == 3); // In game mode?

View File

@ -128,7 +128,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (const cWindow & a_Window) override;
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override;
virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override;
virtual AString GetAuthServerID(void) override { return m_AuthServerID; }

View File

@ -357,7 +357,7 @@ void cProtocolRecognizer::SendHealth(void)
void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value);

View File

@ -131,7 +131,7 @@ public:
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (const cWindow & a_Window) override;
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override;
virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override;
virtual AString GetAuthServerID(void) override;

View File

@ -119,7 +119,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
if (SpreadFurther && (NewMeta < 8))
{
// Spread to the neighbors:
Spread(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
}
// Mark as processed:
@ -130,7 +130,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
void cFloodyFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
void cFloodyFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
{
SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta);
SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);

View File

@ -48,16 +48,13 @@ protected:
bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
/** Checks if the specified block should harden (Water/Lava interaction) and if so, converts it to a suitable block.
*
* Returns whether the block was changed or not.
*/
Returns whether the block was changed or not. */
bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta);
/** Spread water to neighbors.
*
* May be overridden to provide more sophisticated algorithms.
*/
virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
/** Spread fluid to XZ neighbors.
The coords are of the block currently being processed; a_NewMeta is the new meta for the new fluid block.
Descendants may overridde to provide more sophisticated algorithms. */
virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
} ;

View File

@ -35,14 +35,16 @@ cVanillaFluidSimulator::cVanillaFluidSimulator(
void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
void cVanillaFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
{
// Calculate the distance to the nearest "hole" in each direction:
int Cost[4];
Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS);
Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS);
Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS);
Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS);
// Find the minimum distance:
int MinCost = InfiniteCost;
for (unsigned int i = 0; i < ARRAYCOUNT(Cost); ++i)
{
@ -52,6 +54,7 @@ void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, in
}
}
// Spread in all directions where the distance matches the minimum:
if (Cost[0] == MinCost)
{
SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);
@ -86,7 +89,10 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
if (!IsPassableForFluid(BlockType) && !IsBlockLiquid(BlockType))
if (
!IsPassableForFluid(BlockType) || // The block cannot be passed by the liquid ...
(IsAllowedBlock(BlockType) && (BlockMeta == 0)) // ... or if it is liquid, it is a source block
)
{
return Cost;
}
@ -96,7 +102,10 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType))
if (
IsPassableForFluid(BlockType) || // The block can be passed by the liquid ...
(IsBlockLiquid(BlockType) && (BlockMeta != 0)) // ... or it is a liquid and not a source block
)
{
// Path found, exit
return a_Iteration;

View File

@ -30,7 +30,7 @@ public:
protected:
// cFloodyFluidSimulator overrides:
virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override;
virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override;
/** Recursively calculates the minimum number of blocks needed to descend a level. */
int CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration = 0);

View File

@ -237,7 +237,7 @@ public:
{
ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_String);
AString res;
res.assign(m_Data + m_Tags[(size_t)a_Tag].m_DataStart, m_Tags[(size_t)a_Tag].m_DataLength);
res.assign(m_Data + m_Tags[(size_t)a_Tag].m_DataStart, (size_t)m_Tags[(size_t)a_Tag].m_DataLength);
return res;
}
@ -245,7 +245,7 @@ public:
inline AString GetName(int a_Tag) const
{
AString res;
res.assign(m_Data + m_Tags[(size_t)a_Tag].m_NameStart, m_Tags[(size_t)a_Tag].m_NameLength);
res.assign(m_Data + m_Tags[(size_t)a_Tag].m_NameStart, (size_t)m_Tags[(size_t)a_Tag].m_NameLength);
return res;
}