Merge pull request #1826 from mc-server/UnifyPacketizer
Unify packetizer
This commit is contained in:
commit
e5a7a730ed
File diff suppressed because it is too large
Load Diff
@ -73,13 +73,15 @@
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
typedef signed long long Int64;
|
||||
typedef signed int Int32;
|
||||
typedef signed short Int16;
|
||||
typedef signed char Int8;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
typedef unsigned char UInt8;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
@ -245,7 +247,3 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
#define LOGERROR printf
|
||||
#define LOGINFO printf
|
||||
#define LOGWARNING printf
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Server.h"
|
||||
#include "../../src/Logger.h"
|
||||
#include "../../src/LoggerListeners.h"
|
||||
|
||||
|
||||
|
||||
@ -12,8 +14,16 @@
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
// Initialize logging subsystem:
|
||||
cLogger::InitiateMultithreading();
|
||||
auto consoleLogListener = MakeConsoleListener();
|
||||
auto fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
|
||||
int ListenPort = (argc > 1) ? atoi(argv[1]) : 25564;
|
||||
int ConnectPort = (argc > 2) ? atoi(argv[2]) : 25565;
|
||||
printf("Initializing ProtoProxy. Listen port %d, connect port %d.\n", ListenPort, ConnectPort);
|
||||
cServer Server;
|
||||
int res = Server.Init(ListenPort, ConnectPort);
|
||||
if (res != 0)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Globals.h"
|
||||
#include "Server.h"
|
||||
#include "Connection.h"
|
||||
#include "../../src/Logger.h"
|
||||
|
||||
|
||||
|
||||
@ -28,15 +29,11 @@ int cServer::Init(short a_ListenPort, short a_ConnectPort)
|
||||
int res = WSAStartup(0x0202, &wsa);
|
||||
if (res != 0)
|
||||
{
|
||||
printf("Cannot initialize WinSock: %d\n", res);
|
||||
LOGERROR("Cannot initialize WinSock: %d", res);
|
||||
return res;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
LOGINFO("Generating protocol encryption keypair...");
|
||||
m_PrivateKey.Generate();
|
||||
m_PublicKeyDER = m_PrivateKey.GetPubKeyDER();
|
||||
|
||||
m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (m_ListenSocket < 0)
|
||||
{
|
||||
@ -45,22 +42,22 @@ int cServer::Init(short a_ListenPort, short a_ConnectPort)
|
||||
#else
|
||||
int err = errno;
|
||||
#endif
|
||||
printf("Failed to create listener socket: %d\n", err);
|
||||
LOGERROR("Failed to create listener socket: %d", err);
|
||||
return err;
|
||||
}
|
||||
sockaddr_in local;
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.sin_family = AF_INET;
|
||||
local.sin_addr.s_addr = 130; // INADDR_ANY; // All interfaces
|
||||
local.sin_addr.s_addr = INADDR_ANY; // All interfaces
|
||||
local.sin_port = htons(a_ListenPort);
|
||||
if (!bind(m_ListenSocket, (sockaddr *)&local, sizeof(local)))
|
||||
if (bind(m_ListenSocket, (sockaddr *)&local, sizeof(local)) != 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int err = WSAGetLastError();
|
||||
#else
|
||||
int err = errno;
|
||||
#endif
|
||||
printf("Failed to bind listener socket: %d\n", err);
|
||||
LOGERROR("Failed to bind listener socket: %d", err);
|
||||
return err;
|
||||
}
|
||||
if (listen(m_ListenSocket, 1) != 0)
|
||||
@ -73,9 +70,12 @@ int cServer::Init(short a_ListenPort, short a_ConnectPort)
|
||||
printf("Failed to listen on socket: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
LOGINFO("Listening on port %d, connecting to localhost:%d", a_ListenPort, a_ConnectPort);
|
||||
|
||||
printf("Listening on port %d, connecting to localhost:%d\n", a_ListenPort, a_ConnectPort);
|
||||
|
||||
LOGINFO("Generating protocol encryption keypair...");
|
||||
m_PrivateKey.Generate();
|
||||
m_PublicKeyDER = m_PrivateKey.GetPubKeyDER();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ class cServer
|
||||
SOCKET m_ListenSocket;
|
||||
cRsaPrivateKey m_PrivateKey;
|
||||
AString m_PublicKeyDER;
|
||||
short m_ConnectPort;
|
||||
UInt16 m_ConnectPort;
|
||||
|
||||
public:
|
||||
cServer(void);
|
||||
@ -32,7 +32,7 @@ public:
|
||||
cRsaPrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
|
||||
const AString & GetPublicKeyDER (void) { return m_PublicKeyDER; }
|
||||
|
||||
short GetConnectPort(void) const { return m_ConnectPort; }
|
||||
UInt16 GetConnectPort(void) const { return m_ConnectPort; }
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -590,7 +590,7 @@ static int tolua_DoWith(lua_State* tolua_S)
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(int, cItemCallback<Ty2> &)
|
||||
bool (Ty1::*Func1)(UInt32, cItemCallback<Ty2> &)
|
||||
>
|
||||
static int tolua_DoWithID(lua_State* tolua_S)
|
||||
{
|
||||
@ -3879,6 +3879,10 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
BindRankManager(tolua_S);
|
||||
BindNetwork(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cEntity");
|
||||
tolua_constant(tolua_S, "INVALID_ID", cEntity::INVALID_ID);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_endmodule(tolua_S);
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
|
||||
{
|
||||
double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width);
|
||||
double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
|
||||
if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage)) >= 0)
|
||||
if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage)) != cEntity::INVALID_ID)
|
||||
{
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
}
|
||||
@ -144,29 +144,37 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
|
||||
|
||||
case E_ITEM_FIRE_CHARGE:
|
||||
{
|
||||
SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20);
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20) != cEntity::INVALID_ID)
|
||||
{
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_ITEM_ARROW:
|
||||
{
|
||||
SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
|
||||
{
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_ITEM_SNOWBALL:
|
||||
{
|
||||
SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
|
||||
{
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case E_ITEM_EGG:
|
||||
{
|
||||
SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
|
||||
{
|
||||
m_Contents.ChangeSlotCount(a_SlotNum, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -188,9 +196,14 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
|
||||
|
||||
|
||||
|
||||
void cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector)
|
||||
UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector)
|
||||
{
|
||||
m_World->CreateProjectile(static_cast<double>(a_BlockX + 0.5), static_cast<double>(a_BlockY + 0.5), static_cast<double>(a_BlockZ + 0.5), a_Kind, nullptr, nullptr, &a_ShootVector);
|
||||
return m_World->CreateProjectile(
|
||||
static_cast<double>(a_BlockX + 0.5),
|
||||
static_cast<double>(a_BlockY + 0.5),
|
||||
static_cast<double>(a_BlockZ + 0.5),
|
||||
a_Kind, nullptr, nullptr, &a_ShootVector
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,8 +24,9 @@ public:
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Spawns a projectile of the given kind in front of the dispenser with the specified speed. */
|
||||
void SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed);
|
||||
/** Spawns a projectile of the given kind in front of the dispenser with the specified speed.
|
||||
Returns the UniqueID of the spawned projectile, or 0 on failure. */
|
||||
UInt32 SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed);
|
||||
|
||||
/** Returns a unit vector in the cardinal direction of where the dispenser is facing. */
|
||||
Vector3d GetShootVector(NIBBLETYPE a_Meta);
|
||||
|
@ -169,7 +169,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
||||
|
||||
Monster->SetPosition(PosX, RelY, PosZ);
|
||||
Monster->SetYaw(Random.NextFloat() * 360.0f);
|
||||
if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != mtInvalidType)
|
||||
if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != cEntity::INVALID_ID)
|
||||
{
|
||||
EntitiesSpawned = true;
|
||||
Chunk->BroadcastSoundParticleEffect(2004, (int)(PosX * 8.0), (int)(RelY * 8.0), (int)(PosZ * 8.0), 0);
|
||||
|
@ -30,14 +30,16 @@ public:
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities: */
|
||||
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) = 0;
|
||||
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: */
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */
|
||||
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0;
|
||||
|
||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) = 0;
|
||||
/** Spawns a mob of the specified type.
|
||||
Returns the mob's UniqueID if recognized and spawned, or cEntity::INVALID_ID on failure. */
|
||||
virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) = 0;
|
||||
|
||||
/** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */
|
||||
virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;
|
||||
/** Spawns an experience orb at the given location with the given reward.
|
||||
Returns the UniqueID of the spawned experience orb, or cEntity::INVALID_ID on failure. */
|
||||
virtual UInt32 SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;
|
||||
|
||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
|
||||
|
@ -81,9 +81,9 @@ public:
|
||||
void TestWrite(void)
|
||||
{
|
||||
cByteBuffer buf(50);
|
||||
buf.WriteVarInt(5);
|
||||
buf.WriteVarInt(300);
|
||||
buf.WriteVarInt(0);
|
||||
buf.WriteVarInt32(5);
|
||||
buf.WriteVarInt32(300);
|
||||
buf.WriteVarInt32(0);
|
||||
AString All;
|
||||
buf.ReadAll(All);
|
||||
assert_test(All.size() == 4);
|
||||
@ -101,8 +101,8 @@ public:
|
||||
assert_test(buf.Write("a", 1));
|
||||
assert_test(buf.CanReadBytes(1));
|
||||
assert_test(buf.GetReadableSpace() == 1);
|
||||
unsigned char v = 0;
|
||||
assert_test(buf.ReadByte(v));
|
||||
UInt8 v = 0;
|
||||
assert_test(buf.ReadBEUInt8(v));
|
||||
assert_test(v == 'a');
|
||||
assert_test(buf.GetReadableSpace() == 0);
|
||||
buf.CommitRead();
|
||||
@ -317,7 +317,7 @@ bool cByteBuffer::CanWriteBytes(size_t a_Count) const
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadChar(char & a_Value)
|
||||
bool cByteBuffer::ReadBEInt8(Int8 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -330,7 +330,7 @@ bool cByteBuffer::ReadChar(char & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadByte(unsigned char & a_Value)
|
||||
bool cByteBuffer::ReadBEUInt8(UInt8 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -343,15 +343,15 @@ bool cByteBuffer::ReadByte(unsigned char & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadBEShort(short & a_Value)
|
||||
bool cByteBuffer::ReadBEInt16(Int16 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
NEEDBYTES(2);
|
||||
Int16 val;
|
||||
UInt16 val;
|
||||
ReadBuf(&val, 2);
|
||||
val = ntohs(val);
|
||||
a_Value = *(reinterpret_cast<short *>(&val));
|
||||
memcpy(&a_Value, &val, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -373,13 +373,15 @@ bool cByteBuffer::ReadBEUInt16(UInt16 & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadBEInt(int & a_Value)
|
||||
bool cByteBuffer::ReadBEInt32(Int32 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
NEEDBYTES(4);
|
||||
ReadBuf(&a_Value, 4);
|
||||
a_Value = (int)ntohl((u_long)a_Value);
|
||||
UInt32 val;
|
||||
ReadBuf(&val, 4);
|
||||
val = ntohl(val);
|
||||
memcpy(&a_Value, &val, 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -415,6 +417,20 @@ bool cByteBuffer::ReadBEInt64(Int64 & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadBEUInt64(UInt64 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
NEEDBYTES(8);
|
||||
ReadBuf(&a_Value, 8);
|
||||
a_Value = NetworkToHostULong8(&a_Value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadBEFloat(float & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
@ -448,7 +464,7 @@ bool cByteBuffer::ReadBool(bool & a_Value)
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
NEEDBYTES(1);
|
||||
char Value = 0;
|
||||
UInt8 Value = 0;
|
||||
ReadBuf(&Value, 1);
|
||||
a_Value = (Value != 0);
|
||||
return true;
|
||||
@ -462,24 +478,19 @@ bool cByteBuffer::ReadBEUTF16String16(AString & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
short Length;
|
||||
if (!ReadBEShort(Length))
|
||||
UInt16 Length;
|
||||
if (!ReadBEUInt16(Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Length < 0)
|
||||
{
|
||||
ASSERT(!"Negative string length? Are you sure?");
|
||||
return true;
|
||||
}
|
||||
return ReadUTF16String(a_Value, (size_t)Length);
|
||||
return ReadUTF16String(a_Value, Length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadVarInt(UInt32 & a_Value)
|
||||
bool cByteBuffer::ReadVarInt32(UInt32 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -490,7 +501,29 @@ bool cByteBuffer::ReadVarInt(UInt32 & a_Value)
|
||||
{
|
||||
NEEDBYTES(1);
|
||||
ReadBuf(&b, 1);
|
||||
Value = Value | (((UInt32)(b & 0x7f)) << Shift);
|
||||
Value = Value | ((static_cast<UInt32>(b & 0x7f)) << Shift);
|
||||
Shift += 7;
|
||||
} while ((b & 0x80) != 0);
|
||||
a_Value = Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadVarInt64(UInt64 & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
UInt64 Value = 0;
|
||||
int Shift = 0;
|
||||
unsigned char b = 0;
|
||||
do
|
||||
{
|
||||
NEEDBYTES(1);
|
||||
ReadBuf(&b, 1);
|
||||
Value = Value | ((static_cast<UInt64>(b & 0x7f)) << Shift);
|
||||
Shift += 7;
|
||||
} while ((b & 0x80) != 0);
|
||||
a_Value = Value;
|
||||
@ -540,7 +573,7 @@ bool cByteBuffer::ReadLEInt(int & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||
bool cByteBuffer::ReadPosition64(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||
{
|
||||
CHECK_THREAD
|
||||
Int64 Value;
|
||||
@ -565,7 +598,7 @@ bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteChar(char a_Value)
|
||||
bool cByteBuffer::WriteBEInt8(Int8 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -577,7 +610,7 @@ bool cByteBuffer::WriteChar(char a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteByte(unsigned char a_Value)
|
||||
bool cByteBuffer::WriteBEUInt8(UInt8 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -589,33 +622,48 @@ bool cByteBuffer::WriteByte(unsigned char a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEShort(short a_Value)
|
||||
bool cByteBuffer::WriteBEInt16(Int16 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
PUTBYTES(2);
|
||||
u_short Converted = htons((u_short)a_Value);
|
||||
return WriteBuf(&Converted, 2);
|
||||
UInt16 val;
|
||||
memcpy(&val, &a_Value, 2);
|
||||
val = htons(val);
|
||||
return WriteBuf(&val, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEUShort(unsigned short a_Value)
|
||||
bool cByteBuffer::WriteBEUInt16(UInt16 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
PUTBYTES(2);
|
||||
u_short Converted = htons((u_short)a_Value);
|
||||
return WriteBuf(&Converted, 2);
|
||||
a_Value = htons(a_Value);
|
||||
return WriteBuf(&a_Value, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEInt(int a_Value)
|
||||
bool cByteBuffer::WriteBEInt32(Int32 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
PUTBYTES(4);
|
||||
UInt32 Converted = HostToNetwork4(&a_Value);
|
||||
return WriteBuf(&Converted, 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEUInt32(UInt32 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -641,6 +689,19 @@ bool cByteBuffer::WriteBEInt64(Int64 a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEUInt64(UInt64 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
PUTBYTES(8);
|
||||
UInt64 Converted = HostToNetwork8(&a_Value);
|
||||
return WriteBuf(&Converted, 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteBEFloat(float a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
@ -672,14 +733,15 @@ bool cByteBuffer::WriteBool(bool a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
return WriteChar(a_Value ? 1 : 0);
|
||||
UInt8 val = a_Value ? 1 : 0;
|
||||
return Write(&val, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteVarInt(UInt32 a_Value)
|
||||
bool cByteBuffer::WriteVarInt32(UInt32 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
@ -700,12 +762,35 @@ bool cByteBuffer::WriteVarInt(UInt32 a_Value)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteVarInt64(UInt64 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
|
||||
// A 64-bit integer can be encoded by at most 10 bytes:
|
||||
unsigned char b[10];
|
||||
size_t idx = 0;
|
||||
do
|
||||
{
|
||||
b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00);
|
||||
a_Value = a_Value >> 7;
|
||||
idx++;
|
||||
} while (a_Value > 0);
|
||||
|
||||
return WriteBuf(b, idx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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((UInt32)(a_Value.size()));
|
||||
bool res = WriteVarInt32(static_cast<UInt32>(a_Value.size()));
|
||||
if (!res)
|
||||
{
|
||||
return false;
|
||||
@ -717,15 +802,15 @@ bool cByteBuffer::WriteVarUTF8String(const AString & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WriteLEInt(int a_Value)
|
||||
bool cByteBuffer::WriteLEInt32(Int32 a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
CheckValid();
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
return WriteBuf((const char *)&a_Value, 4);
|
||||
return WriteBuf(reinterpret_cast<const char *>(&a_Value), 4);
|
||||
#else
|
||||
int Value = ((a_Value >> 24) & 0xff) | ((a_Value >> 16) & 0xff00) | ((a_Value >> 8) & 0xff0000) | (a_Value & 0xff000000);
|
||||
return WriteBuf((const char *)&Value, 4);
|
||||
return WriteBuf(reinterpret_cast<const char *>(&Value), 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -733,10 +818,15 @@ bool cByteBuffer::WriteLEInt(int a_Value)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
bool cByteBuffer::WritePosition64(Int32 a_BlockX, Int32 a_BlockY, Int32 a_BlockZ)
|
||||
{
|
||||
CHECK_THREAD
|
||||
return WriteBEInt64(((Int64)a_BlockX & 0x3FFFFFF) << 38 | ((Int64)a_BlockY & 0xFFF) << 26 | ((Int64)a_BlockZ & 0x3FFFFFF));
|
||||
CheckValid();
|
||||
return WriteBEInt64(
|
||||
(static_cast<Int64>(a_BlockX & 0x3FFFFFF) << 38) |
|
||||
(static_cast<Int64>(a_BlockY & 0xFFF) << 26) |
|
||||
(static_cast<Int64>(a_BlockZ & 0x3FFFFFF))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,48 +52,53 @@ public:
|
||||
bool CanWriteBytes(size_t a_Count) const;
|
||||
|
||||
// Read the specified datatype and advance the read pointer; return true if successfully read:
|
||||
bool ReadChar (char & a_Value);
|
||||
bool ReadByte (unsigned char & a_Value);
|
||||
bool ReadBEShort (short & a_Value);
|
||||
bool ReadBEUInt16 (UInt16 & a_Value);
|
||||
bool ReadBEInt (int & a_Value);
|
||||
bool ReadBEUInt32 (UInt32 & a_Value);
|
||||
bool ReadBEInt8 (Int8 & a_Value);
|
||||
bool ReadBEInt16 (Int16 & a_Value);
|
||||
bool ReadBEInt32 (Int32 & a_Value);
|
||||
bool ReadBEInt64 (Int64 & a_Value);
|
||||
bool ReadBEUInt8 (UInt8 & a_Value);
|
||||
bool ReadBEUInt16 (UInt16 & a_Value);
|
||||
bool ReadBEUInt32 (UInt32 & a_Value);
|
||||
bool ReadBEUInt64 (UInt64 & a_Value);
|
||||
bool ReadBEFloat (float & a_Value);
|
||||
bool ReadBEDouble (double & a_Value);
|
||||
bool ReadBool (bool & a_Value);
|
||||
bool ReadBEUTF16String16(AString & a_Value); // string length as BE short, then string as UTF-16BE
|
||||
bool ReadVarInt (UInt32 & a_Value);
|
||||
bool ReadVarInt32 (UInt32 & a_Value);
|
||||
bool ReadVarInt64 (UInt64 & a_Value);
|
||||
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||
bool ReadLEInt (int & a_Value);
|
||||
bool ReadPosition (int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
||||
bool ReadPosition64 (int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
||||
|
||||
/** Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...) */
|
||||
/** Reads VarInt, assigns it to anything that can be assigned from an UInt64 (unsigned short, char, Byte, double, ...) */
|
||||
template <typename T> bool ReadVarInt(T & a_Value)
|
||||
{
|
||||
UInt32 v;
|
||||
bool res = ReadVarInt(v);
|
||||
UInt64 v;
|
||||
bool res = ReadVarInt64(v);
|
||||
if (res)
|
||||
{
|
||||
a_Value = v;
|
||||
a_Value = static_cast<T>(v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Write the specified datatype; return true if successfully written
|
||||
bool WriteChar (char a_Value);
|
||||
bool WriteByte (unsigned char a_Value);
|
||||
bool WriteBEShort (short a_Value);
|
||||
bool WriteBEUShort (unsigned short a_Value);
|
||||
bool WriteBEInt (int a_Value);
|
||||
bool WriteBEInt8 (Int8 a_Value);
|
||||
bool WriteBEInt16 (Int16 a_Value);
|
||||
bool WriteBEInt32 (Int32 a_Value);
|
||||
bool WriteBEInt64 (Int64 a_Value);
|
||||
bool WriteBEUInt8 (UInt8 a_Value);
|
||||
bool WriteBEUInt16 (UInt16 a_Value);
|
||||
bool WriteBEUInt32 (UInt32 a_Value);
|
||||
bool WriteBEUInt64 (UInt64 a_Value);
|
||||
bool WriteBEFloat (float a_Value);
|
||||
bool WriteBEDouble (double a_Value);
|
||||
bool WriteBool (bool a_Value);
|
||||
bool WriteVarInt (UInt32 a_Value);
|
||||
bool WriteVarInt32 (UInt32 a_Value);
|
||||
bool WriteVarInt64 (UInt64 a_Value);
|
||||
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||
bool WriteLEInt (int a_Value);
|
||||
bool WritePosition (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
bool WriteLEInt32 (Int32 a_Value);
|
||||
bool WritePosition64 (Int32 a_BlockX, Int32 a_BlockY, Int32 a_BlockZ);
|
||||
|
||||
/** Reads a_Count bytes into a_Buffer; returns true if successful */
|
||||
bool ReadBuf(void * a_Buffer, size_t a_Count);
|
||||
|
@ -1969,7 +1969,7 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
|
||||
|
||||
|
||||
|
||||
bool cChunk::HasEntity(int a_EntityID)
|
||||
bool cChunk::HasEntity(UInt32 a_EntityID)
|
||||
{
|
||||
for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
||||
{
|
||||
@ -2027,7 +2027,7 @@ bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult)
|
||||
bool cChunk::DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult)
|
||||
{
|
||||
// The entity list is locked by the parent chunkmap's CS
|
||||
for (cEntityList::iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
|
||||
@ -2814,7 +2814,7 @@ void cChunk::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude)
|
||||
void cChunk::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
@ -2822,7 +2822,7 @@ void cChunk::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_bl
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendBlockBreakAnim(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage);
|
||||
(*itr)->SendBlockBreakAnim(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ public:
|
||||
|
||||
void AddEntity(cEntity * a_Entity);
|
||||
void RemoveEntity(cEntity * a_Entity);
|
||||
bool HasEntity(int a_EntityID);
|
||||
bool HasEntity(UInt32 a_EntityID);
|
||||
|
||||
/** Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true */
|
||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||
@ -251,7 +251,7 @@ public:
|
||||
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
|
||||
bool DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult); // Lua-accessible
|
||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackResult); // Lua-accessible
|
||||
|
||||
/** Calls the callback for each block entity; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||
bool ForEachBlockEntity(cBlockEntityCallback & a_Callback); // Lua-accessible
|
||||
@ -317,7 +317,7 @@ public:
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
|
@ -373,19 +373,19 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude)
|
||||
void cChunkMap::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
int ChunkX, ChunkZ;
|
||||
|
||||
cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ);
|
||||
cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastBlockBreakAnimation(a_entityID, a_blockX, a_blockY, a_blockZ, a_stage, a_Exclude);
|
||||
Chunk->BroadcastBlockBreakAnimation(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
@ -1753,7 +1753,7 @@ void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity)
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::HasEntity(int a_UniqueID)
|
||||
bool cChunkMap::HasEntity(UInt32 a_UniqueID)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
|
||||
@ -2045,7 +2045,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
|
||||
bool cChunkMap::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
bool res = false;
|
||||
@ -2996,7 +2996,7 @@ bool cChunkMap::cChunkLayer::ForEachEntity(cEntityCallback & a_Callback)
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::cChunkLayer::DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn)
|
||||
bool cChunkMap::cChunkLayer::DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn)
|
||||
{
|
||||
// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found.
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||
@ -3016,7 +3016,7 @@ bool cChunkMap::cChunkLayer::DoWithEntityByID(int a_EntityID, cEntityCallback &
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::cChunkLayer::HasEntity(int a_EntityID)
|
||||
bool cChunkMap::cChunkLayer::HasEntity(UInt32 a_EntityID)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||
void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
|
||||
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
@ -217,7 +217,7 @@ public:
|
||||
void AddEntityIfNotPresent(cEntity * a_Entity);
|
||||
|
||||
/** Returns true if the entity with specified ID is present in the chunks */
|
||||
bool HasEntity(int a_EntityID);
|
||||
bool HasEntity(UInt32 a_EntityID);
|
||||
|
||||
/** Removes the entity from its appropriate chunk */
|
||||
void RemoveEntity(cEntity * a_Entity);
|
||||
@ -236,61 +236,80 @@ public:
|
||||
/** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */
|
||||
void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected);
|
||||
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. */
|
||||
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Lua-accessible
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
||||
Returns true if entity found and callback returned false. */
|
||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each block entity in the specified chunk.
|
||||
Returns true if all block entities processed, false if the callback aborted by returning true. */
|
||||
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each chest in the specified chunk.
|
||||
Returns true if all chests processed, false if the callback aborted by returning true. */
|
||||
bool ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for each dispenser in the specified chunk; returns true if all dispensers processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each dispenser in the specified chunk.
|
||||
Returns true if all dispensers processed, false if the callback aborted by returning true. */
|
||||
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback);
|
||||
|
||||
/** Calls the callback for each dropper in the specified chunk; returns true if all droppers processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each dropper in the specified chunk.
|
||||
Returns true if all droppers processed, false if the callback aborted by returning true. */
|
||||
bool ForEachDropperInChunk(int a_ChunkX, int a_ChunkZ, cDropperCallback & a_Callback);
|
||||
|
||||
/** Calls the callback for each dropspenser in the specified chunk; returns true if all dropspensers processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each dropspenser in the specified chunk.
|
||||
Returns true if all dropspensers processed, false if the callback aborted by returning true. */
|
||||
bool ForEachDropSpenserInChunk(int a_ChunkX, int a_ChunkZ, cDropSpenserCallback & a_Callback);
|
||||
|
||||
/** Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true */
|
||||
/** Calls the callback for each furnace in the specified chunk.
|
||||
Returns true if all furnaces processed, false if the callback aborted by returning true. */
|
||||
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||
/** Calls the callback for the block entity at the specified coords.
|
||||
Returns false if there's no block entity at those coords, true if found. */
|
||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
||||
/** Calls the callback for the beacon at the specified coords.
|
||||
Returns false if there's no beacon at those coords, true if found. */
|
||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
|
||||
/** Calls the callback for the chest at the specified coords.
|
||||
Returns false if there's no chest at those coords, true if found. */
|
||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/** Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the dispenser at the specified coords.
|
||||
Returns false if there's no dispenser at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the dropper at the specified coords; returns false if there's no dropper at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the dropper at the specified coords.
|
||||
Returns false if there's no dropper at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithDropperAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropperCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the dropspenser at the specified coords; returns false if there's no dropspenser at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the dropspenser at the specified coords.
|
||||
Returns false if there's no dropspenser at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithDropSpenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDropSpenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the furnace at the specified coords.
|
||||
Returns false if there's no furnace at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the noteblock at the specified coords.
|
||||
Returns false if there's no noteblock at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the command block at the specified coords.
|
||||
Returns false if there's no command block at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the mob head block at the specified coords.
|
||||
Returns false if there's no mob head block at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
||||
/** Calls the callback for the flower pot at the specified coords.
|
||||
Returns false if there's no flower pot at those coords or callback returns true, returns true if found. */
|
||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||
/** Retrieves the test on the sign at the specified coords.
|
||||
Returns false if there's no sign at those coords, true if found. */
|
||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||
|
||||
/** Touches the chunk, causing it to be loaded or generated */
|
||||
@ -423,10 +442,10 @@ private:
|
||||
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found. */
|
||||
bool DoWithEntityByID(int a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn); // Lua-accessible
|
||||
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback, bool & a_CallbackReturn); // Lua-accessible
|
||||
|
||||
/** Returns true if there is an entity with the specified ID within this layer's chunks */
|
||||
bool HasEntity(int a_EntityID);
|
||||
bool HasEntity(UInt32 a_EntityID);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -676,7 +676,7 @@ bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Usernam
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem)
|
||||
void cClientHandle::HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_HeldItem, eClickAction a_ClickAction)
|
||||
{
|
||||
// This is for creative Inventory changes
|
||||
if (!m_Player->IsGameModeCreative())
|
||||
@ -690,18 +690,18 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel
|
||||
return;
|
||||
}
|
||||
|
||||
m_Player->GetWindow()->Clicked(*m_Player, 0, a_SlotNum, (a_SlotNum >= 0) ? caLeftClick : caLeftClickOutside, a_HeldItem);
|
||||
m_Player->GetWindow()->Clicked(*m_Player, 0, a_SlotNum, a_ClickAction, a_HeldItem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleEnchantItem(Byte a_WindowID, Byte a_Enchantment)
|
||||
void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
|
||||
{
|
||||
if (a_Enchantment > 2)
|
||||
{
|
||||
LOGWARNING("%s attempt to crash the server with invalid enchanting selection!", GetUsername().c_str());
|
||||
LOGWARNING("%s attempt to crash the server with invalid enchanting selection (%u)!", GetUsername().c_str(), a_Enchantment);
|
||||
Kick("Invalid enchanting!");
|
||||
return;
|
||||
}
|
||||
@ -951,7 +951,7 @@ void cClientHandle::HandleCommandBlockBlockChange(int a_BlockX, int a_BlockY, in
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleCommandBlockEntityChange(int a_EntityID, const AString & a_NewCommand)
|
||||
void cClientHandle::HandleCommandBlockEntityChange(UInt32 a_EntityID, const AString & a_NewCommand)
|
||||
{
|
||||
// TODO
|
||||
LOGWARNING("%s: Not implemented yet", __FUNCTION__);
|
||||
@ -978,7 +978,7 @@ void cClientHandle::HandleAnvilItemName(const AString & a_ItemName)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status)
|
||||
void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, UInt8 a_Status)
|
||||
{
|
||||
LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i",
|
||||
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status
|
||||
@ -1515,7 +1515,7 @@ void cClientHandle::HandleAnimation(int a_Animation)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleSlotSelected(short a_SlotNum)
|
||||
void cClientHandle::HandleSlotSelected(Int16 a_SlotNum)
|
||||
{
|
||||
m_Player->GetInventory().SetEquippedSlotNum(a_SlotNum);
|
||||
m_Player->GetWorld()->BroadcastEntityEquipment(*m_Player, 0, m_Player->GetInventory().GetEquippedItem(), this);
|
||||
@ -1534,7 +1534,7 @@ void cClientHandle::HandleSteerVehicle(float a_Forward, float a_Sideways)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleWindowClose(char a_WindowID)
|
||||
void cClientHandle::HandleWindowClose(UInt8 a_WindowID)
|
||||
{
|
||||
m_Player->CloseWindowIfID(a_WindowID);
|
||||
}
|
||||
@ -1543,7 +1543,7 @@ void cClientHandle::HandleWindowClose(char a_WindowID)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem)
|
||||
void cClientHandle::HandleWindowClick(UInt8 a_WindowID, Int16 a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem)
|
||||
{
|
||||
LOGD("WindowClick: WinID %d, SlotNum %d, action: %s, Item %s x %d",
|
||||
a_WindowID, a_SlotNum, ClickActionToString(a_ClickAction),
|
||||
@ -1581,7 +1581,7 @@ void cClientHandle::HandleUpdateSign(
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick)
|
||||
void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
|
||||
{
|
||||
// TODO: Let plugins interfere via a hook
|
||||
|
||||
@ -1726,7 +1726,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleEntityCrouch(int a_EntityID, bool a_IsCrouching)
|
||||
void cClientHandle::HandleEntityCrouch(UInt32 a_EntityID, bool a_IsCrouching)
|
||||
{
|
||||
if (a_EntityID != m_Player->GetUniqueID())
|
||||
{
|
||||
@ -1741,7 +1741,7 @@ void cClientHandle::HandleEntityCrouch(int a_EntityID, bool a_IsCrouching)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleEntityLeaveBed(int a_EntityID)
|
||||
void cClientHandle::HandleEntityLeaveBed(UInt32 a_EntityID)
|
||||
{
|
||||
if (a_EntityID != m_Player->GetUniqueID())
|
||||
{
|
||||
@ -1758,7 +1758,7 @@ void cClientHandle::HandleEntityLeaveBed(int a_EntityID)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleEntitySprinting(int a_EntityID, bool a_IsSprinting)
|
||||
void cClientHandle::HandleEntitySprinting(UInt32 a_EntityID, bool a_IsSprinting)
|
||||
{
|
||||
if (a_EntityID != m_Player->GetUniqueID())
|
||||
{
|
||||
@ -2030,7 +2030,7 @@ void cClientHandle::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, ch
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage)
|
||||
void cClientHandle::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage)
|
||||
{
|
||||
m_Protocol->SendBlockBreakAnim(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ public: // tolua_export
|
||||
// (Please keep these alpha-sorted)
|
||||
void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||
void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType);
|
||||
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
|
||||
void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
|
||||
void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export
|
||||
void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes);
|
||||
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
|
||||
@ -276,16 +276,18 @@ public: // tolua_export
|
||||
|
||||
/** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new
|
||||
command in the command block UI, for an entity-based commandblock (minecart?). */
|
||||
void HandleCommandBlockEntityChange(int a_EntityID, const AString & a_NewCommand);
|
||||
void HandleCommandBlockEntityChange(UInt32 a_EntityID, const AString & a_NewCommand);
|
||||
|
||||
void HandleCreativeInventory (short a_SlotNum, const cItem & a_HeldItem);
|
||||
/** Called when the client clicks the creative inventory window.
|
||||
a_ClickAction specifies whether the click was inside the window or not (caLeftClick or caLeftClickOutside). */
|
||||
void HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_HeldItem, eClickAction a_ClickAction);
|
||||
|
||||
/** Called when the player enchants an Item in the Enchanting table UI. */
|
||||
void HandleEnchantItem(Byte a_WindowID, Byte a_Enchantment);
|
||||
void HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment);
|
||||
|
||||
void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching);
|
||||
void HandleEntityLeaveBed (int a_EntityID);
|
||||
void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting);
|
||||
void HandleEntityCrouch (UInt32 a_EntityID, bool a_IsCrouching);
|
||||
void HandleEntityLeaveBed (UInt32 a_EntityID);
|
||||
void HandleEntitySprinting (UInt32 a_EntityID, bool a_IsSprinting);
|
||||
|
||||
/** Kicks the client if the same username is already logged in.
|
||||
Returns false if the client has been kicked, true otherwise. */
|
||||
@ -298,7 +300,7 @@ public: // tolua_export
|
||||
bool HandleHandshake (const AString & a_Username);
|
||||
|
||||
void HandleKeepAlive (int a_KeepAliveID);
|
||||
void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status);
|
||||
void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, UInt8 a_Status);
|
||||
|
||||
/** Called when the protocol receives a MC|TrSel packet, indicating that the player used a trade in
|
||||
the NPC UI. */
|
||||
@ -312,7 +314,7 @@ public: // tolua_export
|
||||
void HandlePluginMessage (const AString & a_Channel, const AString & a_Message);
|
||||
void HandleRespawn (void);
|
||||
void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem);
|
||||
void HandleSlotSelected (short a_SlotNum);
|
||||
void HandleSlotSelected (Int16 a_SlotNum);
|
||||
void HandleSteerVehicle (float Forward, float Sideways);
|
||||
void HandleTabCompletion (const AString & a_Text);
|
||||
void HandleUpdateSign (
|
||||
@ -321,9 +323,9 @@ public: // tolua_export
|
||||
const AString & a_Line3, const AString & a_Line4
|
||||
);
|
||||
void HandleUnmount (void);
|
||||
void HandleUseEntity (int a_TargetEntityID, bool a_IsLeftClick);
|
||||
void HandleWindowClick (char a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem);
|
||||
void HandleWindowClose (char a_WindowID);
|
||||
void HandleUseEntity (UInt32 a_TargetEntityID, bool a_IsLeftClick);
|
||||
void HandleWindowClick (UInt8 a_WindowID, Int16 a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem);
|
||||
void HandleWindowClose (UInt8 a_WindowID);
|
||||
|
||||
/** Called when the protocol has finished logging the user in.
|
||||
Return true to allow the user in; false to kick them.
|
||||
|
@ -59,6 +59,18 @@ inline Int64 NetworkToHostLong8(const void * a_Value)
|
||||
|
||||
|
||||
|
||||
inline UInt64 NetworkToHostULong8(const void * a_Value)
|
||||
{
|
||||
UInt64 buf;
|
||||
memcpy(&buf, a_Value, 8);
|
||||
buf = ntohll(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline float NetworkToHostFloat4(const void * a_Value)
|
||||
{
|
||||
UInt32 buf;
|
||||
|
@ -18,49 +18,50 @@
|
||||
|
||||
|
||||
|
||||
int cEntity::m_EntityCount = 0;
|
||||
UInt32 cEntity::m_EntityCount = 0;
|
||||
cCriticalSection cEntity::m_CSCount;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height)
|
||||
: m_UniqueID(0)
|
||||
, m_Health(1)
|
||||
, m_MaxHealth(1)
|
||||
, m_AttachedTo(nullptr)
|
||||
, m_Attachee(nullptr)
|
||||
, m_bDirtyHead(true)
|
||||
, m_bDirtyOrientation(true)
|
||||
, m_bHasSentNoSpeed(true)
|
||||
, m_bOnGround(false)
|
||||
, m_Gravity(-9.81f)
|
||||
, m_LastPos(a_X, a_Y, a_Z)
|
||||
, m_IsInitialized(false)
|
||||
, m_WorldTravellingFrom(nullptr)
|
||||
, m_EntityType(a_EntityType)
|
||||
, m_World(nullptr)
|
||||
, m_IsFireproof(false)
|
||||
, m_TicksSinceLastBurnDamage(0)
|
||||
, m_TicksSinceLastLavaDamage(0)
|
||||
, m_TicksSinceLastFireDamage(0)
|
||||
, m_TicksLeftBurning(0)
|
||||
, m_TicksSinceLastVoidDamage(0)
|
||||
, m_IsSwimming(false)
|
||||
, m_IsSubmerged(false)
|
||||
, m_AirLevel(0)
|
||||
, m_AirTickTimer(0)
|
||||
, m_TicksAlive(0)
|
||||
, m_HeadYaw(0.0)
|
||||
, m_Rot(0.0, 0.0, 0.0)
|
||||
, m_Pos(a_X, a_Y, a_Z)
|
||||
, m_WaterSpeed(0, 0, 0)
|
||||
, m_Mass (0.001) // Default 1g
|
||||
, m_Width(a_Width)
|
||||
, m_Height(a_Height)
|
||||
, m_InvulnerableTicks(0)
|
||||
cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height):
|
||||
m_UniqueID(INVALID_ID), // Proper ID will be assigned later in the constructor code
|
||||
m_Health(1),
|
||||
m_MaxHealth(1),
|
||||
m_AttachedTo(nullptr),
|
||||
m_Attachee(nullptr),
|
||||
m_bDirtyHead(true),
|
||||
m_bDirtyOrientation(true),
|
||||
m_bHasSentNoSpeed(true),
|
||||
m_bOnGround(false),
|
||||
m_Gravity(-9.81f),
|
||||
m_LastPos(a_X, a_Y, a_Z),
|
||||
m_IsInitialized(false),
|
||||
m_WorldTravellingFrom(nullptr),
|
||||
m_EntityType(a_EntityType),
|
||||
m_World(nullptr),
|
||||
m_IsFireproof(false),
|
||||
m_TicksSinceLastBurnDamage(0),
|
||||
m_TicksSinceLastLavaDamage(0),
|
||||
m_TicksSinceLastFireDamage(0),
|
||||
m_TicksLeftBurning(0),
|
||||
m_TicksSinceLastVoidDamage(0),
|
||||
m_IsSwimming(false),
|
||||
m_IsSubmerged(false),
|
||||
m_AirLevel(0),
|
||||
m_AirTickTimer(0),
|
||||
m_TicksAlive(0),
|
||||
m_HeadYaw(0.0),
|
||||
m_Rot(0.0, 0.0, 0.0),
|
||||
m_Pos(a_X, a_Y, a_Z),
|
||||
m_WaterSpeed(0, 0, 0),
|
||||
m_Mass (0.001), // Default 1g
|
||||
m_Width(a_Width),
|
||||
m_Height(a_Height),
|
||||
m_InvulnerableTicks(0)
|
||||
{
|
||||
// Assign a proper ID:
|
||||
cCSLock Lock(m_CSCount);
|
||||
m_EntityCount++;
|
||||
m_UniqueID = m_EntityCount;
|
||||
|
@ -142,6 +142,10 @@ public:
|
||||
|
||||
static const int VOID_BOUNDARY = -46; ///< Y position to begin applying void damage
|
||||
static const int FALL_DAMAGE_HEIGHT = 4; ///< Y difference after which fall damage is applied
|
||||
|
||||
/** Special ID that is considered an "invalid value", signifying no entity. */
|
||||
static const UInt32 INVALID_ID = 0; // Exported to Lua in ManualBindings.cpp, ToLua doesn't parse initialized constants.
|
||||
|
||||
|
||||
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
|
||||
virtual ~cEntity();
|
||||
@ -248,7 +252,7 @@ public:
|
||||
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways);
|
||||
void SteerVehicle(float a_Forward, float a_Sideways);
|
||||
|
||||
inline int GetUniqueID(void) const { return m_UniqueID; }
|
||||
inline UInt32 GetUniqueID(void) const { return m_UniqueID; }
|
||||
inline bool IsDestroyed(void) const { return !m_IsInitialized; }
|
||||
|
||||
/// Schedules the entity for destroying; if a_ShouldBroadcast is set to true, broadcasts the DestroyEntity packet
|
||||
@ -464,12 +468,15 @@ public:
|
||||
|
||||
protected:
|
||||
static cCriticalSection m_CSCount;
|
||||
static int m_EntityCount;
|
||||
static UInt32 m_EntityCount;
|
||||
|
||||
/** Measured in meter/second (m/s) */
|
||||
Vector3d m_Speed;
|
||||
|
||||
int m_UniqueID;
|
||||
/** The ID of the entity that is guaranteed to be unique within a single run of the server.
|
||||
Always nonzero (a zero UniqueID (cEntity::INVALID_ID) is used for error reporting).
|
||||
Note that the UniqueID is not persisted through storage. */
|
||||
UInt32 m_UniqueID;
|
||||
|
||||
int m_Health;
|
||||
int m_MaxHealth;
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the item in the frame */
|
||||
const cItem & GetItem(void) { return m_Item; }
|
||||
const cItem & GetItem(void) const { return m_Item; }
|
||||
|
||||
/** Set the item in the frame */
|
||||
void SetItem(cItem & a_Item) { m_Item = a_Item; }
|
||||
|
@ -24,7 +24,7 @@ class cMinecartCollisionCallback :
|
||||
public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, int a_UniqueID, int a_AttacheeUniqueID) :
|
||||
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, UInt32 a_UniqueID, UInt32 a_AttacheeUniqueID) :
|
||||
m_DoesInteserct(false),
|
||||
m_CollidedEntityPos(0, 0, 0),
|
||||
m_Pos(a_Pos),
|
||||
@ -77,8 +77,8 @@ protected:
|
||||
|
||||
Vector3d m_Pos;
|
||||
double m_Height, m_Width;
|
||||
int m_UniqueID;
|
||||
int m_AttacheeUniqueID;
|
||||
UInt32 m_UniqueID;
|
||||
UInt32 m_AttacheeUniqueID;
|
||||
};
|
||||
|
||||
|
||||
@ -824,7 +824,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
||||
|
||||
bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
|
||||
{
|
||||
cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == nullptr) ? -1 : m_Attachee->GetUniqueID()));
|
||||
cMinecartCollisionCallback MinecartCollisionCallback(
|
||||
GetPosition(), GetHeight(), GetWidth(), GetUniqueID(),
|
||||
((m_Attachee == nullptr) ? cEntity::INVALID_ID : m_Attachee->GetUniqueID())
|
||||
);
|
||||
int ChunkX, ChunkZ;
|
||||
cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ);
|
||||
m_World->ForEachEntityInChunk(ChunkX, ChunkZ, MinecartCollisionCallback);
|
||||
|
@ -221,7 +221,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
|
||||
super(etProjectile, a_X, a_Y, a_Z, a_Width, a_Height),
|
||||
m_ProjectileKind(a_Kind),
|
||||
m_CreatorData(
|
||||
((a_Creator != nullptr) ? a_Creator->GetUniqueID() : -1),
|
||||
((a_Creator != nullptr) ? a_Creator->GetUniqueID() : cEntity::INVALID_ID),
|
||||
((a_Creator != nullptr) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""),
|
||||
((a_Creator != nullptr) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments())
|
||||
),
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
/** Returns the unique ID of the entity who created this projectile
|
||||
May return an ID <0
|
||||
*/
|
||||
int GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; }
|
||||
UInt32 GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; }
|
||||
|
||||
/** Returns the name of the player that created the projectile
|
||||
Will be empty for non-player creators
|
||||
@ -90,18 +90,17 @@ public:
|
||||
protected:
|
||||
|
||||
/** A structure that stores the Entity ID and Playername of the projectile's creator
|
||||
Used to migitate invalid pointers caused by the creator being destroyed
|
||||
*/
|
||||
Used to migitate invalid pointers caused by the creator being destroyed. */
|
||||
struct CreatorData
|
||||
{
|
||||
CreatorData(int a_UniqueID, const AString & a_Name, const cEnchantments & a_Enchantments) :
|
||||
CreatorData(UInt32 a_UniqueID, const AString & a_Name, const cEnchantments & a_Enchantments) :
|
||||
m_UniqueID(a_UniqueID),
|
||||
m_Name(a_Name),
|
||||
m_Enchantments(a_Enchantments)
|
||||
{
|
||||
}
|
||||
|
||||
const int m_UniqueID;
|
||||
const UInt32 m_UniqueID;
|
||||
AString m_Name;
|
||||
cEnchantments m_Enchantments;
|
||||
};
|
||||
@ -110,8 +109,7 @@ protected:
|
||||
eKind m_ProjectileKind;
|
||||
|
||||
/** The structure for containing the entity ID and name who has created this projectile
|
||||
The ID and/or name may be nullptr (e.g. for dispensers/mobs)
|
||||
*/
|
||||
The ID and/or name may be nullptr (e.g. for dispensers/mobs). */
|
||||
CreatorData m_CreatorData;
|
||||
|
||||
/** True if the projectile has hit the ground and is stuck there */
|
||||
|
@ -132,13 +132,15 @@
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
typedef signed long long Int64;
|
||||
typedef signed int Int32;
|
||||
typedef signed short Int16;
|
||||
typedef signed char Int8;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
typedef unsigned char UInt8;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
@ -156,10 +158,12 @@ class SizeChecker<T, Size, true>
|
||||
template class SizeChecker<Int64, 8>;
|
||||
template class SizeChecker<Int32, 4>;
|
||||
template class SizeChecker<Int16, 2>;
|
||||
template class SizeChecker<Int8, 1>;
|
||||
|
||||
template class SizeChecker<UInt64, 8>;
|
||||
template class SizeChecker<UInt32, 4>;
|
||||
template class SizeChecker<UInt16, 2>;
|
||||
template class SizeChecker<UInt8, 1>;
|
||||
|
||||
// A macro to disallow the copy constructor and operator = functions
|
||||
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
Vector3d Pos = a_Player->GetThrowStartPos();
|
||||
Vector3d Speed = a_Player->GetLookVector() * 7;
|
||||
|
||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, cProjectileEntity::pkSplashPotion, a_Player, &a_Player->GetEquippedItem(), &Speed) < 0)
|
||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, cProjectileEntity::pkSplashPotion, a_Player, &a_Player->GetEquippedItem(), &Speed) == cEntity::INVALID_ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
eMonsterType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage);
|
||||
if (
|
||||
(MonsterType != mtInvalidType) && // Valid monster type
|
||||
(a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) >= 0)) // Spawning succeeded
|
||||
(a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) != cEntity::INVALID_ID)) // Spawning succeeded
|
||||
{
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
cFastRandom Random;
|
||||
a_World->BroadcastSoundEffect("random.bow", a_Player->GetPosX(), a_Player->GetPosY() - a_Player->GetHeight(), a_Player->GetPosZ(), 0.5f, 0.4f / (Random.NextFloat(1.0f) * 0.4f + 0.8f));
|
||||
|
||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, &a_Player->GetEquippedItem(), &Speed) < 0)
|
||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, &a_Player->GetEquippedItem(), &Speed) == cEntity::INVALID_ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -135,7 +135,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, &a_Player->GetEquippedItem()) < 0)
|
||||
if (a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, &a_Player->GetEquippedItem()) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include "Logger.h"
|
||||
#include "OSSupport/File.h"
|
||||
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ cMapManager::cMapManager(cWorld * a_World)
|
||||
|
||||
|
||||
|
||||
bool cMapManager::DoWithMap(int a_ID, cMapCallback & a_Callback)
|
||||
bool cMapManager::DoWithMap(UInt32 a_ID, cMapCallback & a_Callback)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
cMap * Map = GetMapData(a_ID);
|
||||
|
@ -32,8 +32,7 @@ public:
|
||||
cMapManager(cWorld * a_World);
|
||||
|
||||
/** Returns the map with the specified ID, nullptr if out of range.
|
||||
WARNING: The returned map object is not thread safe.
|
||||
*/
|
||||
WARNING: The returned map object is not thread safe. */
|
||||
cMap * GetMapData(unsigned int a_ID);
|
||||
|
||||
/** Creates a new map. Returns nullptr on error */
|
||||
@ -41,13 +40,11 @@ public:
|
||||
|
||||
/** Calls the callback for the map with the specified ID.
|
||||
Returns true if the map was found and the callback called, false if map not found.
|
||||
Callback return value is ignored.
|
||||
*/
|
||||
bool DoWithMap(int a_ID, cMapCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
Callback return value is ignored. */
|
||||
bool DoWithMap(UInt32 a_ID, cMapCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Calls the callback for each map.
|
||||
Returns true if all maps processed, false if the callback aborted by returning true.
|
||||
*/
|
||||
Returns true if all maps processed, false if the callback aborted by returning true. */
|
||||
bool ForEachMap(cMapCallback & a_Callback);
|
||||
|
||||
size_t GetNumMaps(void) const; // tolua_export
|
||||
|
@ -67,30 +67,29 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
}
|
||||
AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER);
|
||||
|
||||
if ((a_Killer != nullptr) && a_Killer->IsProjectile() && (((cProjectileEntity *)a_Killer)->GetCreatorUniqueID() >= 0))
|
||||
// If the creeper was killed by a skeleton, add a random music disc drop:
|
||||
if (
|
||||
(a_Killer != nullptr) &&
|
||||
a_Killer->IsProjectile() &&
|
||||
((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID))
|
||||
{
|
||||
class cProjectileCreatorCallback : public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cProjectileCreatorCallback(void)
|
||||
{
|
||||
}
|
||||
cProjectileCreatorCallback(void) {}
|
||||
|
||||
virtual bool Item(cEntity * a_Entity) override
|
||||
{
|
||||
if (a_Entity->IsMob() && ((cMonster *)a_Entity)->GetMobType() == mtSkeleton)
|
||||
if (a_Entity->IsMob() && ((reinterpret_cast<cMonster *>(a_Entity))->GetMobType() == mtSkeleton))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
cProjectileCreatorCallback PCC;
|
||||
if (GetWorld()->DoWithEntityByID(((cProjectileEntity *)a_Killer)->GetCreatorUniqueID(), PCC))
|
||||
} PCC;
|
||||
if (GetWorld()->DoWithEntityByID((reinterpret_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID(), PCC))
|
||||
{
|
||||
// 12 music discs. TickRand starts from 0 to 11. Disk IDs start at 2256, so add that. There.
|
||||
AddRandomDropItem(a_Drops, 1, 1, (short)m_World->GetTickRandomNumber(11) + 2256);
|
||||
AddRandomDropItem(a_Drops, 1, 1, static_cast<short>(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,22 +10,22 @@
|
||||
class cCriticalSection
|
||||
{
|
||||
public:
|
||||
|
||||
void Lock(void);
|
||||
void Unlock(void);
|
||||
|
||||
// IsLocked/IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined
|
||||
// The fake versions (in Release) will not effect the program in any way
|
||||
#ifdef _DEBUG
|
||||
cCriticalSection(void);
|
||||
bool IsLocked(void);
|
||||
bool IsLockedByCurrentThread(void);
|
||||
cCriticalSection(void);
|
||||
bool IsLocked(void);
|
||||
bool IsLockedByCurrentThread(void);
|
||||
#else
|
||||
bool IsLocked(void) { return false; }
|
||||
bool IsLockedByCurrentThread(void) { return false; }
|
||||
bool IsLocked(void) { return false; }
|
||||
bool IsLockedByCurrentThread(void) { return false; }
|
||||
#endif // _DEBUG
|
||||
|
||||
private:
|
||||
|
||||
#ifdef _DEBUG
|
||||
int m_IsLocked; // Number of times this CS is locked
|
||||
std::thread::id m_OwningThreadID;
|
||||
|
@ -8,19 +8,23 @@ SET (SRCS
|
||||
Authenticator.cpp
|
||||
ChunkDataSerializer.cpp
|
||||
MojangAPI.cpp
|
||||
Packetizer.cpp
|
||||
Protocol17x.cpp
|
||||
Protocol18x.cpp
|
||||
ProtocolRecognizer.cpp)
|
||||
ProtocolRecognizer.cpp
|
||||
)
|
||||
|
||||
SET (HDRS
|
||||
Authenticator.h
|
||||
ChunkDataSerializer.h
|
||||
MojangAPI.h
|
||||
Packetizer.h
|
||||
Protocol.h
|
||||
Protocol17x.h
|
||||
Protocol18x.h
|
||||
ProtocolRecognizer.h)
|
||||
ProtocolRecognizer.h
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
if (NOT MSVC)
|
||||
add_library(Protocol ${SRCS} ${HDRS})
|
||||
endif()
|
||||
|
@ -187,11 +187,11 @@ void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_Chu
|
||||
|
||||
// Create the packet:
|
||||
cByteBuffer Packet(512 KiB);
|
||||
Packet.WriteVarInt(0x21); // Packet id (Chunk Data packet)
|
||||
Packet.WriteBEInt(a_ChunkX);
|
||||
Packet.WriteBEInt(a_ChunkZ);
|
||||
Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag
|
||||
Packet.WriteBEUShort(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff
|
||||
Packet.WriteVarInt32(0x21); // Packet id (Chunk Data packet)
|
||||
Packet.WriteBEInt32(a_ChunkX);
|
||||
Packet.WriteBEInt32(a_ChunkZ);
|
||||
Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag
|
||||
Packet.WriteBEUInt16(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff
|
||||
|
||||
// Write the chunk size:
|
||||
const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
|
||||
@ -201,15 +201,15 @@ void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_Chu
|
||||
sizeof(m_BlockSkyLight) + // Block sky light
|
||||
BiomeDataSize // Biome data
|
||||
);
|
||||
Packet.WriteVarInt(ChunkSize);
|
||||
Packet.WriteVarInt32(ChunkSize);
|
||||
|
||||
// Write the block types to the packet:
|
||||
for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++)
|
||||
{
|
||||
BLOCKTYPE BlockType = m_BlockTypes[Index] & 0xFF;
|
||||
NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f;
|
||||
Packet.WriteByte((unsigned char)(BlockType << 4) | BlockMeta);
|
||||
Packet.WriteByte((unsigned char)(BlockType >> 4));
|
||||
Packet.WriteBEUInt8(static_cast<unsigned char>(BlockType << 4) | BlockMeta);
|
||||
Packet.WriteBEUInt8(static_cast<unsigned char>(BlockType >> 4));
|
||||
}
|
||||
|
||||
// Write the rest:
|
||||
@ -234,8 +234,8 @@ void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_Chu
|
||||
else
|
||||
{
|
||||
AString PostData;
|
||||
Buffer.WriteVarInt((UInt32)Packet.GetUsedSpace() + 1);
|
||||
Buffer.WriteVarInt(0);
|
||||
Buffer.WriteVarInt32(static_cast<UInt32>(Packet.GetUsedSpace() + 1));
|
||||
Buffer.WriteVarInt32(0);
|
||||
Buffer.ReadAll(PostData);
|
||||
Buffer.CommitRead();
|
||||
|
||||
|
101
src/Protocol/Packetizer.cpp
Normal file
101
src/Protocol/Packetizer.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
|
||||
// Packetizer.cpp
|
||||
|
||||
// Implements the cPacketizer class representing a wrapper for sending a single packet over a protocol.
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Packetizer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Converts the hex digit character to its value. */
|
||||
static UInt8 HexDigitValue(char a_Character)
|
||||
{
|
||||
switch (a_Character)
|
||||
{
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': return 10;
|
||||
case 'b': return 11;
|
||||
case 'c': return 12;
|
||||
case 'd': return 13;
|
||||
case 'e': return 14;
|
||||
case 'f': return 15;
|
||||
case 'A': return 10;
|
||||
case 'B': return 11;
|
||||
case 'C': return 12;
|
||||
case 'D': return 13;
|
||||
case 'E': return 14;
|
||||
case 'F': return 15;
|
||||
default:
|
||||
{
|
||||
LOGWARNING("Bad hex digit: %c", a_Character);
|
||||
ASSERT(!"Bad hex digit");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cPacketizer:
|
||||
|
||||
cPacketizer::~cPacketizer()
|
||||
{
|
||||
m_Protocol.SendPacket(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPacketizer::WriteByteAngle(double a_Angle)
|
||||
{
|
||||
WriteBEInt8(static_cast<Int8>(255 * a_Angle / 360));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPacketizer::WriteFPInt(double a_Value)
|
||||
{
|
||||
WriteBEInt32(static_cast<Int32>(a_Value * 32));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPacketizer::WriteUUID(const AString & a_UUID)
|
||||
{
|
||||
if (a_UUID.length() != 32)
|
||||
{
|
||||
LOGWARNING("%s: Attempt to send a bad uuid (length isn't 32): %s", __FUNCTION__, a_UUID.c_str());
|
||||
ASSERT(!"Wrong uuid length!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 32; i += 2)
|
||||
{
|
||||
auto val = static_cast<UInt8>(HexDigitValue(a_UUID[i]) << 4 | HexDigitValue(a_UUID[i + 1]));
|
||||
VERIFY(m_Out.WriteBEUInt8(val));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
155
src/Protocol/Packetizer.h
Normal file
155
src/Protocol/Packetizer.h
Normal file
@ -0,0 +1,155 @@
|
||||
|
||||
// Packetizer.h
|
||||
|
||||
// Declares the cPacketizer class representing a wrapper for sending a single packet over a protocol.
|
||||
// The class provides auto-locking, serialization and send-on-instance-destroy semantics
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Protocol.h"
|
||||
#include "../ByteBuffer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Composes an individual packet in the protocol's m_OutPacketBuffer; sends it just before being destructed. */
|
||||
class cPacketizer
|
||||
{
|
||||
public:
|
||||
/** Starts serializing a new packet into the protocol's m_OutPacketBuffer.
|
||||
Locks the protocol's m_CSPacket to avoid multithreading issues. */
|
||||
cPacketizer(cProtocol & a_Protocol, UInt32 a_PacketType) :
|
||||
m_Protocol(a_Protocol),
|
||||
m_Out(a_Protocol.m_OutPacketBuffer),
|
||||
m_Lock(a_Protocol.m_CSPacket),
|
||||
m_PacketType(a_PacketType) // Used for logging purposes
|
||||
{
|
||||
m_Out.WriteVarInt32(a_PacketType);
|
||||
}
|
||||
|
||||
/** Sends the packet via the contained protocol's SendPacket() function. */
|
||||
~cPacketizer();
|
||||
|
||||
inline void WriteBool(bool a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBool(a_Value));
|
||||
}
|
||||
|
||||
inline void WriteBEUInt8(UInt8 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEUInt8(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEInt8(Int8 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEInt8(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEInt16(Int16 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEInt16(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEUInt16(short a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEUInt16(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEInt32(Int32 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEInt32(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEUInt32(UInt32 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEUInt32(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEInt64(Int64 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEInt64(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEUInt64(UInt64 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEUInt64(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEFloat(float a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEFloat(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBEDouble(double a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteBEDouble(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteVarInt32(UInt32 a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteVarInt32(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteString(const AString & a_Value)
|
||||
{
|
||||
VERIFY(m_Out.WriteVarUTF8String(a_Value));
|
||||
}
|
||||
|
||||
|
||||
inline void WriteBuf(const char * a_Data, size_t a_Size)
|
||||
{
|
||||
VERIFY(m_Out.Write(a_Data, a_Size));
|
||||
}
|
||||
|
||||
|
||||
/** Writes the specified block position as a single encoded 64-bit BigEndian integer. */
|
||||
inline void WritePosition64(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
VERIFY(m_Out.WritePosition64(a_BlockX, a_BlockY, a_BlockZ));
|
||||
}
|
||||
|
||||
/** Writes the specified angle using a single byte. */
|
||||
void WriteByteAngle(double a_Angle);
|
||||
|
||||
/** Writes the double value as a 27:5 fixed-point integer. */
|
||||
void WriteFPInt(double a_Value);
|
||||
|
||||
/** Writes the specified UUID as a 128-bit BigEndian integer. */
|
||||
void WriteUUID(const AString & a_UUID);
|
||||
|
||||
UInt32 GetPacketType(void) const { return m_PacketType; }
|
||||
|
||||
protected:
|
||||
/** The protocol instance in which the packet is being constructed. */
|
||||
cProtocol & m_Protocol;
|
||||
|
||||
/** The protocol's buffer for the constructed packet data. */
|
||||
cByteBuffer & m_Out;
|
||||
|
||||
/** The RAII lock preventing multithreaded access to the protocol buffer while constructing the packet. */
|
||||
cCSLock m_Lock;
|
||||
|
||||
/** Type of the contained packet.
|
||||
Used for logging purposes, the packet type is encoded into m_Out immediately in constructor. */
|
||||
UInt32 m_PacketType;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../Endianness.h"
|
||||
#include "../Scoreboard.h"
|
||||
#include "../Map.h"
|
||||
#include "../ByteBuffer.h"
|
||||
|
||||
|
||||
|
||||
@ -32,6 +33,7 @@ class cChunkDataSerializer;
|
||||
class cFallingBlock;
|
||||
class cCompositeChat;
|
||||
class cStatManager;
|
||||
class cPacketizer;
|
||||
|
||||
|
||||
|
||||
@ -47,7 +49,9 @@ class cProtocol
|
||||
{
|
||||
public:
|
||||
cProtocol(cClientHandle * a_Client) :
|
||||
m_Client(a_Client)
|
||||
m_Client(a_Client),
|
||||
m_OutPacketBuffer(64 KiB),
|
||||
m_OutPacketLenBuffer(20) // 20 bytes is more than enough for one VarInt
|
||||
{
|
||||
}
|
||||
|
||||
@ -59,7 +63,7 @@ public:
|
||||
// Sending stuff to clients (alphabetically sorted):
|
||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) = 0;
|
||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0;
|
||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0;
|
||||
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0;
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
|
||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
|
||||
virtual void SendChat (const AString & a_Message) = 0;
|
||||
@ -136,11 +140,27 @@ public:
|
||||
virtual AString GetAuthServerID(void) = 0;
|
||||
|
||||
protected:
|
||||
cClientHandle * m_Client;
|
||||
cCriticalSection m_CSPacket; // Each SendXYZ() function must acquire this CS in order to send the whole packet at once
|
||||
friend class cPacketizer;
|
||||
|
||||
/// A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it
|
||||
cClientHandle * m_Client;
|
||||
|
||||
/** Provides synchronization for sending the entire packet at once.
|
||||
Each SendXYZ() function must acquire this CS in order to send the whole packet at once.
|
||||
Automated via cPacketizer class. */
|
||||
cCriticalSection m_CSPacket;
|
||||
|
||||
/** Buffer for composing the outgoing packets, through cPacketizer */
|
||||
cByteBuffer m_OutPacketBuffer;
|
||||
|
||||
/** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */
|
||||
cByteBuffer m_OutPacketLenBuffer;
|
||||
|
||||
/** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */
|
||||
virtual void SendData(const char * a_Data, size_t a_Size) = 0;
|
||||
|
||||
/** Sends a single packet contained within the cPacketizer class.
|
||||
The cPacketizer's destructor calls this to send the contained packet; protocol may transform the data (compression in 1.8 etc). */
|
||||
virtual void SendPacket(cPacketizer & a_Packet) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -63,7 +63,7 @@ public:
|
||||
/** Sending stuff to clients (alphabetically sorted): */
|
||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
|
||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
@ -140,89 +140,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
/** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */
|
||||
class cPacketizer
|
||||
{
|
||||
public:
|
||||
cPacketizer(cProtocol172 & a_Protocol, UInt32 a_PacketType) :
|
||||
m_Protocol(a_Protocol),
|
||||
m_Out(a_Protocol.m_OutPacketBuffer),
|
||||
m_Lock(a_Protocol.m_CSPacket)
|
||||
{
|
||||
m_Out.WriteVarInt(a_PacketType);
|
||||
}
|
||||
|
||||
~cPacketizer();
|
||||
|
||||
void WriteBool(bool a_Value)
|
||||
{
|
||||
m_Out.WriteBool(a_Value);
|
||||
}
|
||||
|
||||
void WriteByte(Byte a_Value)
|
||||
{
|
||||
m_Out.WriteByte(a_Value);
|
||||
}
|
||||
|
||||
void WriteChar(char a_Value)
|
||||
{
|
||||
m_Out.WriteChar(a_Value);
|
||||
}
|
||||
|
||||
void WriteShort(short a_Value)
|
||||
{
|
||||
m_Out.WriteBEShort(a_Value);
|
||||
}
|
||||
|
||||
void WriteInt(int a_Value)
|
||||
{
|
||||
m_Out.WriteBEInt(a_Value);
|
||||
}
|
||||
|
||||
void WriteInt64(Int64 a_Value)
|
||||
{
|
||||
m_Out.WriteBEInt64(a_Value);
|
||||
}
|
||||
|
||||
void WriteFloat(float a_Value)
|
||||
{
|
||||
m_Out.WriteBEFloat(a_Value);
|
||||
}
|
||||
|
||||
void WriteDouble(double a_Value)
|
||||
{
|
||||
m_Out.WriteBEDouble(a_Value);
|
||||
}
|
||||
|
||||
void WriteVarInt(UInt32 a_Value)
|
||||
{
|
||||
m_Out.WriteVarInt(a_Value);
|
||||
}
|
||||
|
||||
void WriteString(const AString & a_Value)
|
||||
{
|
||||
m_Out.WriteVarUTF8String(a_Value);
|
||||
}
|
||||
|
||||
void WriteBuf(const char * a_Data, size_t a_Size)
|
||||
{
|
||||
m_Out.Write(a_Data, a_Size);
|
||||
}
|
||||
|
||||
void WriteItem(const cItem & a_Item);
|
||||
void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte
|
||||
void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer
|
||||
void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f
|
||||
void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob
|
||||
void WriteEntityProperties(const cEntity & a_Entity); // Writes the entity properties for the specified entity, including the Count field
|
||||
void WriteBlockEntity(const cBlockEntity & a_BlockEntity);
|
||||
|
||||
protected:
|
||||
cProtocol172 & m_Protocol;
|
||||
cByteBuffer & m_Out;
|
||||
cCSLock m_Lock;
|
||||
} ;
|
||||
|
||||
AString m_ServerAddress;
|
||||
|
||||
UInt16 m_ServerPort;
|
||||
@ -235,12 +152,6 @@ protected:
|
||||
/** Buffer for the received data */
|
||||
cByteBuffer m_ReceivedData;
|
||||
|
||||
/** Buffer for composing the outgoing packets, through cPacketizer */
|
||||
cByteBuffer m_OutPacketBuffer;
|
||||
|
||||
/** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */
|
||||
cByteBuffer m_OutPacketLenBuffer;
|
||||
|
||||
bool m_IsEncrypted;
|
||||
|
||||
cAesCfb128Decryptor m_Decryptor;
|
||||
@ -297,11 +208,14 @@ protected:
|
||||
|
||||
/** Parses Vanilla plugin messages into specific ClientHandle calls.
|
||||
The message payload is still in the bytebuffer, to be read by this function. */
|
||||
void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, short a_PayloadLength);
|
||||
void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, UInt16 a_PayloadLength);
|
||||
|
||||
/** Sends the data to the client, encrypting them if needed. */
|
||||
virtual void SendData(const char * a_Data, size_t a_Size) override;
|
||||
|
||||
/** Sends the packet to the client. Called by the cPacketizer's destructor. */
|
||||
virtual void SendPacket(cPacketizer & a_Packet) override;
|
||||
|
||||
void SendCompass(const cWorld & a_World);
|
||||
|
||||
/** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */
|
||||
@ -312,6 +226,24 @@ protected:
|
||||
|
||||
void StartEncryption(const Byte * a_Key);
|
||||
|
||||
/** Converts the BlockFace received by the protocol into eBlockFace constants.
|
||||
If the received value doesn't match any of our eBlockFace constants, BLOCK_FACE_NONE is returned. */
|
||||
eBlockFace FaceIntToBlockFace(Int8 a_FaceInt);
|
||||
|
||||
/** Writes the item data into a packet. */
|
||||
void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
|
||||
|
||||
/** Writes the metadata for the specified entity, not including the terminating 0x7f. */
|
||||
void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the mob-specific metadata for the specified mob */
|
||||
void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
|
||||
|
||||
/** Writes the entity properties for the specified entity, including the Count field. */
|
||||
void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the block entity data for the specified block entity into the packet. */
|
||||
void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity);
|
||||
} ;
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@ public:
|
||||
/** Sending stuff to clients (alphabetically sorted): */
|
||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
|
||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
@ -150,96 +150,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
/** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */
|
||||
class cPacketizer
|
||||
{
|
||||
public:
|
||||
cPacketizer(cProtocol180 & a_Protocol, UInt32 a_PacketType) :
|
||||
m_Protocol(a_Protocol),
|
||||
m_Out(a_Protocol.m_OutPacketBuffer),
|
||||
m_Lock(a_Protocol.m_CSPacket)
|
||||
{
|
||||
m_Out.WriteVarInt(a_PacketType);
|
||||
}
|
||||
|
||||
~cPacketizer();
|
||||
|
||||
void WriteBool(bool a_Value)
|
||||
{
|
||||
m_Out.WriteBool(a_Value);
|
||||
}
|
||||
|
||||
void WriteByte(Byte a_Value)
|
||||
{
|
||||
m_Out.WriteByte(a_Value);
|
||||
}
|
||||
|
||||
void WriteChar(char a_Value)
|
||||
{
|
||||
m_Out.WriteChar(a_Value);
|
||||
}
|
||||
|
||||
void WriteShort(short a_Value)
|
||||
{
|
||||
m_Out.WriteBEShort(a_Value);
|
||||
}
|
||||
|
||||
void WriteInt(int a_Value)
|
||||
{
|
||||
m_Out.WriteBEInt(a_Value);
|
||||
}
|
||||
|
||||
void WriteInt64(Int64 a_Value)
|
||||
{
|
||||
m_Out.WriteBEInt64(a_Value);
|
||||
}
|
||||
|
||||
void WriteFloat(float a_Value)
|
||||
{
|
||||
m_Out.WriteBEFloat(a_Value);
|
||||
}
|
||||
|
||||
void WriteDouble(double a_Value)
|
||||
{
|
||||
m_Out.WriteBEDouble(a_Value);
|
||||
}
|
||||
|
||||
void WriteVarInt(UInt32 a_Value)
|
||||
{
|
||||
m_Out.WriteVarInt(a_Value);
|
||||
}
|
||||
|
||||
void WriteString(const AString & a_Value)
|
||||
{
|
||||
m_Out.WriteVarUTF8String(a_Value);
|
||||
}
|
||||
|
||||
void WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
void WriteUUID(const AString & a_UUID);
|
||||
|
||||
void WriteBuf(const char * a_Data, size_t a_Size)
|
||||
{
|
||||
m_Out.Write(a_Data, a_Size);
|
||||
}
|
||||
|
||||
void WriteItem(const cItem & a_Item);
|
||||
void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte
|
||||
void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer
|
||||
void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f
|
||||
void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob
|
||||
void WriteEntityProperties(const cEntity & a_Entity); // Writes the entity properties for the specified entity, including the Count field
|
||||
void WriteBlockEntity(const cBlockEntity & a_BlockEntity);
|
||||
|
||||
protected:
|
||||
cProtocol180 & m_Protocol;
|
||||
cByteBuffer & m_Out;
|
||||
cCSLock m_Lock;
|
||||
} ;
|
||||
|
||||
AString m_ServerAddress;
|
||||
|
||||
UInt16 m_ServerPort;
|
||||
@ -252,12 +162,6 @@ protected:
|
||||
/** Buffer for the received data */
|
||||
cByteBuffer m_ReceivedData;
|
||||
|
||||
/** Buffer for composing the outgoing packets, through cPacketizer */
|
||||
cByteBuffer m_OutPacketBuffer;
|
||||
|
||||
/** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */
|
||||
cByteBuffer m_OutPacketLenBuffer;
|
||||
|
||||
bool m_IsEncrypted;
|
||||
|
||||
cAesCfb128Decryptor m_Decryptor;
|
||||
@ -320,6 +224,9 @@ protected:
|
||||
/** Sends the data to the client, encrypting them if needed. */
|
||||
virtual void SendData(const char * a_Data, size_t a_Size) override;
|
||||
|
||||
/** Sends the packet to the client. Called by the cPacketizer's destructor. */
|
||||
virtual void SendPacket(cPacketizer & a_Packet) override;
|
||||
|
||||
void SendCompass(const cWorld & a_World);
|
||||
|
||||
/** Reads an item out of the received data, sets a_Item to the values read.
|
||||
@ -332,6 +239,24 @@ protected:
|
||||
|
||||
void StartEncryption(const Byte * a_Key);
|
||||
|
||||
/** Converts the BlockFace received by the protocol into eBlockFace constants.
|
||||
If the received value doesn't match any of our eBlockFace constants, BLOCK_FACE_NONE is returned. */
|
||||
eBlockFace FaceIntToBlockFace(Int8 a_FaceInt);
|
||||
|
||||
/** Writes the item data into a packet. */
|
||||
void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
|
||||
|
||||
/** Writes the metadata for the specified entity, not including the terminating 0x7f. */
|
||||
void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the mob-specific metadata for the specified mob */
|
||||
void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
|
||||
|
||||
/** Writes the entity properties for the specified entity, including the Count field. */
|
||||
void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the block entity data for the specified block entity into the packet. */
|
||||
void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity);
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -108,10 +108,10 @@ void cProtocolRecognizer::SendBlockAction(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
|
||||
void cProtocolRecognizer::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage)
|
||||
{
|
||||
ASSERT(m_Protocol != nullptr);
|
||||
m_Protocol->SendBlockBreakAnim(a_entityID, a_BlockX, a_BlockY, a_BlockZ, stage);
|
||||
m_Protocol->SendBlockBreakAnim(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage);
|
||||
}
|
||||
|
||||
|
||||
@ -911,13 +911,13 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
case PROTO_VERSION_1_7_2:
|
||||
{
|
||||
AString ServerAddress;
|
||||
short ServerPort;
|
||||
UInt16 ServerPort;
|
||||
UInt32 NextState;
|
||||
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!m_Buffer.ReadBEShort(ServerPort))
|
||||
if (!m_Buffer.ReadBEUInt16(ServerPort))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -926,19 +926,19 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
break;
|
||||
}
|
||||
m_Buffer.CommitRead();
|
||||
m_Protocol = new cProtocol172(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
||||
m_Protocol = new cProtocol172(m_Client, ServerAddress, ServerPort, NextState);
|
||||
return true;
|
||||
}
|
||||
case PROTO_VERSION_1_7_6:
|
||||
{
|
||||
AString ServerAddress;
|
||||
short ServerPort;
|
||||
UInt16 ServerPort;
|
||||
UInt32 NextState;
|
||||
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!m_Buffer.ReadBEShort(ServerPort))
|
||||
if (!m_Buffer.ReadBEUInt16(ServerPort))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -947,19 +947,19 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
break;
|
||||
}
|
||||
m_Buffer.CommitRead();
|
||||
m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
||||
m_Protocol = new cProtocol176(m_Client, ServerAddress, ServerPort, NextState);
|
||||
return true;
|
||||
}
|
||||
case PROTO_VERSION_1_8_0:
|
||||
{
|
||||
AString ServerAddress;
|
||||
short ServerPort;
|
||||
UInt16 ServerPort;
|
||||
UInt32 NextState;
|
||||
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!m_Buffer.ReadBEShort(ServerPort))
|
||||
if (!m_Buffer.ReadBEUInt16(ServerPort))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -968,12 +968,12 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
break;
|
||||
}
|
||||
m_Buffer.CommitRead();
|
||||
m_Protocol = new cProtocol180(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
||||
m_Protocol = new cProtocol180(m_Client, ServerAddress, ServerPort, NextState);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u)",
|
||||
m_Client->GetIPString().c_str(), ProtocolVersion
|
||||
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))",
|
||||
m_Client->GetIPString().c_str(), ProtocolVersion, ProtocolVersion
|
||||
);
|
||||
m_Client->Kick("Unsupported protocol version");
|
||||
return false;
|
||||
@ -982,3 +982,15 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendPacket(cPacketizer & a_Pkt)
|
||||
{
|
||||
// This function should never be called - it needs to exists so that cProtocolRecognizer can be instantiated,
|
||||
// but the actual sending is done by the internal m_Protocol itself.
|
||||
LOGWARNING("%s: This function shouldn't ever be called.", __FUNCTION__);
|
||||
ASSERT(!"Function not to be called");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
/// Sending stuff to clients (alphabetically sorted):
|
||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
|
||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
@ -136,9 +136,12 @@ protected:
|
||||
|
||||
/** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer; returns true if recognized.
|
||||
The packet length and type have already been read, type is 0
|
||||
The number of bytes remaining in the packet is passed as a_PacketLengthRemaining
|
||||
**/
|
||||
The number of bytes remaining in the packet is passed as a_PacketLengthRemaining. **/
|
||||
bool TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining);
|
||||
|
||||
/** Sends a single packet contained within the cPacketizer class.
|
||||
The cPacketizer's destructor calls this to send the contained packet; protocol may transform the data (compression in 1.8 etc). */
|
||||
virtual void SendPacket(cPacketizer & a_Pkt) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -248,28 +248,31 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
/// Maps player's EntityID -> current recipe; not a std::map because cCraftingGrid needs proper constructor params
|
||||
typedef std::list<std::pair<int, cCraftingRecipe> > cRecipeMap;
|
||||
/** Maps player's EntityID -> current recipe.
|
||||
Not a std::map because cCraftingGrid needs proper constructor params. */
|
||||
typedef std::list<std::pair<UInt32, cCraftingRecipe> > cRecipeMap;
|
||||
|
||||
int m_GridSize;
|
||||
cRecipeMap m_Recipes;
|
||||
|
||||
/// Handles a click in the result slot. Crafts using the current recipe, if possible
|
||||
/** Handles a click in the result slot.
|
||||
Crafts using the current recipe, if possible. */
|
||||
void ClickedResult(cPlayer & a_Player);
|
||||
|
||||
/// Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result.
|
||||
/** Handles a shift-click in the result slot.
|
||||
Crafts using the current recipe until it changes or no more space for result. */
|
||||
void ShiftClickedResult(cPlayer & a_Player);
|
||||
|
||||
/** Handles a drop-click in the result slot. */
|
||||
void DropClickedResult(cPlayer & a_Player);
|
||||
|
||||
/// Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player
|
||||
/** Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player. */
|
||||
void UpdateRecipe(cPlayer & a_Player);
|
||||
|
||||
/// Retrieves the recipe for the specified player from the map, or creates one if not found
|
||||
/** Retrieves the recipe for the specified player from the map, or creates one if not found. */
|
||||
cCraftingRecipe & GetRecipeForPlayer(cPlayer & a_Player);
|
||||
|
||||
/// Called after an item has been crafted to handle statistics e.t.c.
|
||||
/** Called after an item has been crafted to handle statistics e.t.c. */
|
||||
void HandleCraftItem(const cItem & a_Result, cPlayer & a_Player);
|
||||
} ;
|
||||
|
||||
|
@ -1920,7 +1920,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
|
||||
|
||||
|
||||
|
||||
int cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta)
|
||||
UInt32 cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta)
|
||||
{
|
||||
cFallingBlock * FallingBlock = new cFallingBlock(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta);
|
||||
FallingBlock->Initialize(*this);
|
||||
@ -1931,11 +1931,12 @@ int cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NI
|
||||
|
||||
|
||||
|
||||
int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
|
||||
UInt32 cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
|
||||
{
|
||||
if (a_Reward < 1)
|
||||
{
|
||||
return -1;
|
||||
LOGWARNING("%s: Attempting to create an experience orb with non-positive reward!", __FUNCTION__);
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
|
||||
cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward);
|
||||
@ -1947,7 +1948,7 @@ int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
|
||||
|
||||
|
||||
|
||||
int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content, int a_BlockHeight)
|
||||
UInt32 cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content, int a_BlockHeight)
|
||||
{
|
||||
cMinecart * Minecart;
|
||||
switch (a_MinecartType)
|
||||
@ -1959,7 +1960,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
|
||||
case E_ITEM_MINECART_WITH_HOPPER: Minecart = new cMinecartWithHopper (a_X, a_Y, a_Z); break;
|
||||
default:
|
||||
{
|
||||
return -1;
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
} // switch (a_MinecartType)
|
||||
Minecart->Initialize(*this);
|
||||
@ -1970,7 +1971,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
|
||||
|
||||
|
||||
|
||||
void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff)
|
||||
UInt32 cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff)
|
||||
{
|
||||
cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks);
|
||||
TNT->Initialize(*this);
|
||||
@ -1979,6 +1980,7 @@ void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks,
|
||||
a_InitialVelocityCoeff * 2,
|
||||
a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1)
|
||||
);
|
||||
return TNT->GetUniqueID();
|
||||
}
|
||||
|
||||
|
||||
@ -2069,7 +2071,7 @@ void cWorld::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude)
|
||||
void cWorld::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastBlockBreakAnimation(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage, a_Exclude);
|
||||
}
|
||||
@ -2906,7 +2908,7 @@ bool cWorld::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_
|
||||
|
||||
|
||||
|
||||
bool cWorld::DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback)
|
||||
bool cWorld::DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback)
|
||||
{
|
||||
// First check the entities-to-add:
|
||||
{
|
||||
@ -3215,7 +3217,7 @@ void cWorld::AddEntity(cEntity * a_Entity)
|
||||
|
||||
|
||||
|
||||
bool cWorld::HasEntity(int a_UniqueID)
|
||||
bool cWorld::HasEntity(UInt32 a_UniqueID)
|
||||
{
|
||||
// Check if the entity is in the queue to be added to the world:
|
||||
{
|
||||
@ -3332,15 +3334,16 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType)
|
||||
UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType)
|
||||
{
|
||||
cMonster * Monster = nullptr;
|
||||
|
||||
Monster = cMonster::NewMonsterFromType(a_MonsterType);
|
||||
if (Monster != nullptr)
|
||||
if (Monster == nullptr)
|
||||
{
|
||||
Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||
|
||||
return SpawnMobFinalize(Monster);
|
||||
}
|
||||
@ -3348,13 +3351,9 @@ int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a
|
||||
|
||||
|
||||
|
||||
int cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
UInt32 cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
{
|
||||
// Invalid cMonster object. Bail out.
|
||||
if (!a_Monster)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ASSERT(a_Monster != nullptr);
|
||||
|
||||
// Give the mob full health.
|
||||
a_Monster->SetHealth(a_Monster->GetMaxHealth());
|
||||
@ -3364,7 +3363,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
{
|
||||
delete a_Monster;
|
||||
a_Monster = nullptr;
|
||||
return -1;
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
|
||||
// Initialize the monster into the current world.
|
||||
@ -3372,7 +3371,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
{
|
||||
delete a_Monster;
|
||||
a_Monster = nullptr;
|
||||
return -1;
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
|
||||
cPluginManager::Get()->CallHookSpawnedMonster(*this, *a_Monster);
|
||||
@ -3384,18 +3383,18 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||
|
||||
|
||||
|
||||
int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed)
|
||||
UInt32 cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed)
|
||||
{
|
||||
cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed);
|
||||
if (Projectile == nullptr)
|
||||
{
|
||||
return -1;
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
if (!Projectile->Initialize(*this))
|
||||
{
|
||||
delete Projectile;
|
||||
Projectile = nullptr;
|
||||
return -1;
|
||||
return cEntity::INVALID_ID;
|
||||
}
|
||||
return Projectile->GetUniqueID();
|
||||
}
|
||||
|
48
src/World.h
48
src/World.h
@ -216,7 +216,7 @@ public:
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); // tolua_export
|
||||
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||
|
||||
// tolua_begin
|
||||
@ -336,7 +336,9 @@ public:
|
||||
The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */
|
||||
void AddEntity(cEntity * a_Entity);
|
||||
|
||||
bool HasEntity(int a_UniqueID);
|
||||
/** Returns true if an entity with the specified UniqueID exists in the world.
|
||||
Note: Only loaded chunks are considered. */
|
||||
bool HasEntity(UInt32 a_UniqueID);
|
||||
|
||||
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
||||
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
@ -349,8 +351,9 @@ public:
|
||||
If any chunk in the box is missing, ignores the entities in that chunk silently. */
|
||||
bool ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. */
|
||||
bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
/** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param.
|
||||
Returns true if entity found and callback returned false. */
|
||||
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Compares clients of two chunks, calls the callback accordingly */
|
||||
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
|
||||
@ -477,20 +480,25 @@ public:
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities: */
|
||||
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) override;
|
||||
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: */
|
||||
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */
|
||||
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) override;
|
||||
|
||||
/** Spawns an falling block entity at the given position. It returns the UniqueID of the spawned falling block. */
|
||||
int SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta);
|
||||
/** Spawns an falling block entity at the given position.
|
||||
Returns the UniqueID of the spawned falling block, or cEntity::INVALID_ID on failure. */
|
||||
UInt32 SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta);
|
||||
|
||||
/** Spawns an minecart at the given coordinates. */
|
||||
int SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content = cItem(), int a_BlockHeight = 1);
|
||||
/** Spawns an minecart at the given coordinates.
|
||||
Returns the UniqueID of the spawned minecart, or cEntity::INVALID_ID on failure. */
|
||||
UInt32 SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content = cItem(), int a_BlockHeight = 1);
|
||||
|
||||
/** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */
|
||||
virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) override;
|
||||
/** Spawns an experience orb at the given location with the given reward.
|
||||
Returns the UniqueID of the spawned experience orb, or cEntity::INVALID_ID on failure. */
|
||||
virtual UInt32 SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) override;
|
||||
|
||||
/** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */
|
||||
void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1);
|
||||
/** Spawns a new primed TNT entity at the specified block coords and specified fuse duration.
|
||||
Initial velocity is given based on the relative coefficient provided.
|
||||
Returns the UniqueID of the created entity, or cEntity::INVALID_ID on failure. */
|
||||
UInt32 SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1);
|
||||
|
||||
// tolua_end
|
||||
|
||||
@ -796,14 +804,14 @@ public:
|
||||
|
||||
bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
|
||||
|
||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) override; // tolua_export
|
||||
int SpawnMobFinalize(cMonster* a_Monster);
|
||||
/** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, cEntity::INVALID_ID otherwise */
|
||||
virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) override; // tolua_export
|
||||
|
||||
UInt32 SpawnMobFinalize(cMonster * a_Monster);
|
||||
|
||||
/** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise
|
||||
Item parameter used currently for Fireworks to correctly set entity metadata based on item metadata
|
||||
*/
|
||||
int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed = nullptr); // tolua_export
|
||||
/** Creates a projectile of the specified type. Returns the projectile's UniqueID if successful, cEntity::INVALID_ID otherwise
|
||||
Item parameter is currently used for Fireworks to correctly set entity metadata based on item metadata. */
|
||||
UInt32 CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed = nullptr); // tolua_export
|
||||
|
||||
/** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */
|
||||
int GetTickRandomNumber(int a_Range) { return (int)(m_TickRand.randInt(a_Range)); }
|
||||
|
Loading…
Reference in New Issue
Block a user