1
0

Cut out all packet handling to a separate cProtocol descendant

git-svn-id: http://mc-server.googlecode.com/svn/trunk@796 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-08-27 17:31:16 +00:00
parent d97ad781b4
commit 66f4c9e0c0
28 changed files with 1725 additions and 1186 deletions

View File

@ -2404,6 +2404,26 @@
>
</File>
</Filter>
<Filter
Name="Protocol"
>
<File
RelativePath="..\source\Protocol.h"
>
</File>
<File
RelativePath="..\source\Protocol125.cpp"
>
</File>
<File
RelativePath="..\source\Protocol125.h"
>
</File>
<File
RelativePath="..\source\ProtocolRecognizer.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Config files"

View File

@ -488,6 +488,7 @@
<ClCompile Include="..\source\packets\cPacket_WindowClick.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowClose.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowOpen.cpp" />
<ClCompile Include="..\source\Protocol125.cpp" />
<ClCompile Include="..\source\Ravines.cpp" />
<ClCompile Include="..\source\squirrelbindings\SquirrelBindings.cpp" />
<ClCompile Include="..\source\squirrelbindings\SquirrelFunctions.cpp" />
@ -742,6 +743,9 @@
<ClInclude Include="..\source\packets\cPacket_WindowClick.h" />
<ClInclude Include="..\source\packets\cPacket_WindowClose.h" />
<ClInclude Include="..\source\packets\cPacket_WindowOpen.h" />
<ClInclude Include="..\source\Protocol.h" />
<ClInclude Include="..\source\Protocol125.h" />
<ClInclude Include="..\source\ProtocolRecognizer.h" />
<ClInclude Include="..\source\Ravines.h" />
<ClInclude Include="..\source\squirrelbindings\cSquirrelBaseClass.h" />
<ClInclude Include="..\source\squirrelbindings\SquirrelArray.h" />

View File

@ -445,6 +445,9 @@
<Filter Include="cBlockEntity\cNoteEntity">
<UniqueIdentifier>{7bfe7ca2-4966-4eca-a501-94e1bfaa009f}</UniqueIdentifier>
</Filter>
<Filter Include="Protocol">
<UniqueIdentifier>{dcde29da-b011-40c1-b4b0-c39b653ef73c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\source\cServer.cpp">
@ -952,6 +955,9 @@
<Filter>cBlockEntity\cNoteEntity</Filter>
</ClCompile>
<ClCompile Include="..\source\ChunkDataSerializer.cpp" />
<ClCompile Include="..\source\Protocol125.cpp">
<Filter>Protocol</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\source\cServer.h">
@ -1665,6 +1671,15 @@
<Filter>cBlockEntity\cNoteEntity</Filter>
</ClInclude>
<ClInclude Include="..\source\ChunkDataSerializer.h" />
<ClInclude Include="..\source\ProtocolRecognizer.h">
<Filter>Protocol</Filter>
</ClInclude>
<ClInclude Include="..\source\Protocol125.h">
<Filter>Protocol</Filter>
</ClInclude>
<ClInclude Include="..\source\Protocol.h">
<Filter>Protocol</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg">

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/25/12 23:57:06.
** Generated automatically by tolua++-1.0.92 on 08/27/12 16:12:30.
*/
#ifndef __cplusplus
@ -21119,7 +21119,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_SWITCH",E_ITEM_SWITCH);
tolua_constant(tolua_S,"E_ADD_TO_INV",E_ADD_TO_INV);
tolua_constant(tolua_S,"E_ANIMATION",E_ANIMATION);
tolua_constant(tolua_S,"E_PACKET_13",E_PACKET_13);
tolua_constant(tolua_S,"E_PACKET_ENTITY_ACTION",E_PACKET_ENTITY_ACTION);
tolua_constant(tolua_S,"E_NAMED_ENTITY_SPAWN",E_NAMED_ENTITY_SPAWN);
tolua_constant(tolua_S,"E_PICKUP_SPAWN",E_PICKUP_SPAWN);
tolua_constant(tolua_S,"E_COLLECT_ITEM",E_COLLECT_ITEM);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/25/12 23:57:07.
** Generated automatically by tolua++-1.0.92 on 08/27/12 16:12:30.
*/
/* Exported function */

View File

@ -306,6 +306,15 @@ bool cByteBuffer::SkipRead(int a_Count)
void cByteBuffer::ReadAll(AString & a_Data)
{
ReadString(a_Data, GetReadableSpace());
}
void cByteBuffer::CommitRead(void)
{
m_DataStart = m_ReadPos;

View File

@ -68,6 +68,9 @@ public:
/// Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer
bool SkipRead(int a_Count);
/// Reads all available data into a_Data
void ReadAll(AString & a_Data);
/// Removes the bytes that have been read from the ringbuffer
void CommitRead(void);

View File

@ -27,7 +27,7 @@ enum ENUM_PACKET_ID
E_ITEM_SWITCH = 0x10, // OBSOLETE, use E_SLOT_SELECTED instead
E_ADD_TO_INV = 0x11, // TODO: Sure this is not Use Bed??
E_ANIMATION = 0x12,
E_PACKET_13 = 0x13,
E_PACKET_ENTITY_ACTION = 0x13,
E_NAMED_ENTITY_SPAWN = 0x14,
E_PICKUP_SPAWN = 0x15,
E_COLLECT_ITEM = 0x16,

95
source/Protocol.h Normal file
View File

@ -0,0 +1,95 @@
// Protocol.h
// Interfaces to the cProtocol class representing the generic interface that a protocol
// parser and serializer must implement
#pragma once
#include "Defines.h"
class cPlayer;
class cEntity;
class cWindow;
class cInventory;
class cPawn;
class cPickup;
class cMonster;
class cChunkDataSerializer;
class cProtocol
{
public:
cProtocol(cClientHandle * a_Client) :
m_Client(a_Client)
{
}
/// Called when client sends some data
virtual void DataReceived(const char * a_Data, int a_Size) = 0;
// Sending stuff to clients:
virtual void SendDisconnect (const AString & a_Reason) = 0;
virtual void SendLogin (const cPlayer & a_Player) = 0;
virtual void SendHandshake (const AString & a_ServerName) = 0;
virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) = 0;
virtual void SendChat (const AString & a_Message) = 0;
virtual void SendPlayerAnimation (const cPlayer & a_Player, char a_Animation) = 0;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) = 0;
virtual void SendWindowClose (char a_WindowID) = 0;
virtual void SendWholeInventory (const cInventory & a_Inventory) = 0;
virtual void SendWholeInventory (const cWindow & a_Window) = 0;
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) = 0;
virtual void SendPlayerPosition (void) = 0;
virtual void SendRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0;
virtual void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0;
virtual void SendEntLook (const cEntity & a_Entity) = 0;
virtual void SendEntHeadLook (const cEntity & a_Entity) = 0;
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2) = 0;
virtual void SendHealth (void) = 0;
virtual void SendRespawn (void) = 0;
virtual void SendGameMode (eGameMode a_GameMode) = 0;
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
virtual void SendPlayerMoveLook (void) = 0;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) = 0;
virtual void SendMetadata (const cPawn & a_Entity) = 0;
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) = 0;
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0;
virtual void SendSpawnMob (const cMonster & a_Mob) = 0;
virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0;
virtual void SendWeather (eWeather a_Weather) = 0;
virtual void SendTimeUpdate (Int64 a_WorldTime) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
virtual void SendKeepAlive (int a_PingID) = 0;
protected:
cClientHandle * m_Client;
cCriticalSection m_CSPacket; //< Each SendXYZ() function must acquire this CS in order to send the whole packet at once
/// A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it
virtual void SendData(const char * a_Data, int a_Size) = 0;
} ;

1104
source/Protocol125.cpp Normal file

File diff suppressed because it is too large Load Diff

126
source/Protocol125.h Normal file
View File

@ -0,0 +1,126 @@
// Protocol125.h
// Interfaces to the cProtocol125 class representing the release 1.2.5 protocol (#29)
#pragma once
#include "Protocol.h"
#include "ByteBuffer.h"
// fwd:
class cPacket;
class cProtocol125 :
public cProtocol
{
typedef cProtocol super;
public:
cProtocol125(cClientHandle * a_Client);
/// Called when client sends some data:
virtual void DataReceived(const char * a_Data, int a_Size) override;
/// Sending stuff to clients:
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2) override;
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEntHeadLook (const cEntity & a_Entity) override;
virtual void SendEntLook (const cEntity & a_Entity) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHandshake (const AString & a_ServerName) override;
virtual void SendHealth (void) override;
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) override;
virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) override;
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player) override;
virtual void SendMetadata (const cPawn & a_Entity) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAnimation (const cPlayer & a_Player, char a_Animation) override;
virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override;
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPosition (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendRespawn (void) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void SendTimeUpdate (Int64 a_WorldTime) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override;
virtual void SendWeather (eWeather a_Weather) override;
virtual void SendWholeInventory (const cInventory & a_Inventory) override;
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (char a_WindowID) override;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override;
protected:
/// Results of packet-parsing:
enum {
PACKET_OK = 1,
PACKET_ERROR = -1,
PACKET_UNKNOWN = -2,
PACKET_INCOMPLETE = -3,
} ;
cByteBuffer m_ReceivedData; //< Buffer for the received data
void Send(const cPacket & a_Packet);
virtual void SendData(const char * a_Data, int a_Size) override;
/// Parse the packet of the specified type from m_ReceivedData (switch into ParseXYZ() )
virtual int ParsePacket(unsigned char a_PacketType);
// Specific packet parsers:
virtual int ParseKeepAlive (void);
virtual int ParseHandshake (void);
virtual int ParseLogin (void);
virtual int ParsePlayerPosition (void);
virtual int ParsePlayerLook (void);
virtual int ParsePlayerMoveLook (void);
virtual int ParsePlayerAbilities (void);
virtual int ParseChat (void);
virtual int ParseArmAnim (void);
virtual int ParseFlying (void);
virtual int ParseBlockDig (void);
virtual int ParseBlockPlace (void);
virtual int ParseDisconnect (void);
virtual int ParseItemSwitch (void);
virtual int ParseEntityEquipment (void);
virtual int ParseCreativeInventoryAction(void);
virtual int ParseNewInvalidState (void);
virtual int ParsePickupSpawn (void);
virtual int ParseUseEntity (void);
virtual int ParseWindowClose (void);
virtual int ParseWindowClick (void);
virtual int ParseEntityAction (void);
virtual int ParseUpdateSign (void);
virtual int ParseRespawn (void);
virtual int ParsePing (void);
} ;

View File

@ -0,0 +1,78 @@
// ProtocolRecognizer.h
// Interfaces to the cProtocolRecognizer class representing the meta-protocol that recognizes possibly multiple
// protocol versions and redirects everything to them
#pragma once
#include "Protocol.h"
class cProtocolRecognizer :
public cProtocol
{
public:
cProtocolRecognizer(cClientHandle * a_Client);
/// Called when client sends some data:
virtual void DataReceived(const char * a_Data, int a_Size) override;
/// Sending stuff to clients:
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2) override;
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEntHeadLook (const cEntity & a_Entity) override;
virtual void SendEntLook (const cEntity & a_Entity) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHandshake (const AString & a_ServerName) override;
virtual void SendHealth (void) override;
virtual void SendInventoryProgress(char a_WindowID, short a_Progressbar, short a_Value) override;
virtual void SendInventorySlot (int a_WindowID, short a_SlotNum, const cItem & a_Item) override;
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player) override;
virtual void SendMetadata (const cPawn & a_Entity) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAnimation (const cPlayer & a_Player, char a_Animation) override;
virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override;
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPosition (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendRespawn (void) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void SendTimeUpdate (Int64 a_WorldTime) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override;
virtual void SendWeather (eWeather a_Weather) override;
virtual void SendWholeInventory (const cInventory & a_Inventory) override;
virtual void SendWholeInventory (const cWindow & a_Window) override;
virtual void SendWindowClose (char a_WindowID) override;
virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override;
protected:
cProtocol * m_Protocol; //< The recognized protocol
cByteBuffer m_Buffer; //< Buffer used until the protocol is recognized
} ;

View File

@ -1619,115 +1619,6 @@ void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_
/*
// _X 2012_02_23: Loading in old format not supported anymore
/// Loads the chunk from the old-format disk file, erases the file afterwards. Returns true if successful
bool cChunk::LoadFromDisk()
{
AString SourceFile;
Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", m_PosX, m_PosY, m_PosZ );
cFile f;
if (!f.Open(SourceFile, cFile::fmRead))
{
return false;
}
if (f.Read(m_BlockData, sizeof(m_BlockData)) != sizeof(m_BlockData))
{
LOGERROR("ERROR READING FROM FILE %s", SourceFile.c_str());
return false;
}
// Now load Block Entities:
ENUM_BLOCK_ID BlockType;
while (f.Read(&BlockType, sizeof(ENUM_BLOCK_ID)) == sizeof(ENUM_BLOCK_ID))
{
switch (BlockType)
{
case E_BLOCK_CHEST:
{
cChestEntity * ChestEntity = new cChestEntity( 0, 0, 0, m_World );
if (!ChestEntity->LoadFromFile(f))
{
LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile.c_str());
delete ChestEntity;
return false;
}
m_BlockEntities.push_back( ChestEntity );
break;
}
case E_BLOCK_FURNACE:
{
cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0, m_World );
if (!FurnaceEntity->LoadFromFile(f))
{
LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile.c_str());
delete FurnaceEntity;
return false;
}
m_BlockEntities.push_back( FurnaceEntity );
break;
}
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
{
cSignEntity * SignEntity = new cSignEntity(BlockType, 0, 0, 0, m_World );
if (!SignEntity->LoadFromFile( f ) )
{
LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile.c_str());
delete SignEntity;
return false;
}
m_BlockEntities.push_back( SignEntity );
break;
}
default:
{
ASSERT(!"Unhandled block entity in file");
break;
}
}
}
f.Close();
// Delete old format file
if (std::remove(SourceFile.c_str()) != 0)
{
LOGERROR("Could not delete file %s", SourceFile.c_str());
}
else
{
LOGINFO("Successfully deleted old format file \"%s\"", SourceFile.c_str());
}
m_IsDirty = false;
return true;
}
*/
void cChunk::Broadcast( const cPacket * a_Packet, cClientHandle* a_Exclude)
{
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
{
if (*itr == a_Exclude)
{
continue;
}
(*itr)->Send(*a_Packet);
} // for itr - LoadedByClient[]
}
void cChunk::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude)
{
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )

View File

@ -224,44 +224,6 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO
void cChunkMap::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude)
{
// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->Broadcast(a_Packet, a_Exclude);
}
void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude)
{
// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->Broadcast(a_Packet, a_Exclude);
}
void cChunkMap::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);

View File

@ -16,7 +16,6 @@ class cItem;
class MTRand;
class cChunkStay;
class cChunk;
class cPacket;
class cPlayer;
class cChestEntity;
class cFurnaceEntity;
@ -43,13 +42,6 @@ public:
cChunkMap(cWorld* a_World );
~cChunkMap();
// Direct action methods:
/// Broadcast a_Packet to all clients in the chunk specified
void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
/// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, const cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
/// Broadcasts an a_Player's animation to all clients in the chunk where a_Player is
void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL);

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,6 @@
#define CCLIENTHANDLE_H_INCLUDED
#include "Defines.h"
#include "packets/cPacket.h"
#include "Vector3d.h"
#include "cSocketThreads.h"
#include "ChunkDef.h"
@ -29,15 +28,15 @@
class cPlayer;
class cRedstone;
class cChunkDataSerializer;
class cInventory;
class cWindow;
class cMonster;
class cPawn;
class cPickup;
class cMonster;
class cChunkDataSerializer;
class cPlayer;
class cProtocol;
class cRedstone;
class cWindow;
@ -83,8 +82,6 @@ public:
bool IsPlaying(void) const {return (m_State == csPlaying); }
void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL);
void SendDisconnect(const AString & a_Reason);
void SendHandshake (const AString & a_ServerName);
void SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item);
@ -96,7 +93,7 @@ public:
void SendWholeInventory(const cInventory & a_Inventory);
void SendWholeInventory(const cWindow & a_Window);
void SendTeleportEntity(const cEntity & a_Entity);
void SendPlayerListItem(const cPlayer & a_Player);
void SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline);
void SendPlayerPosition(void);
void SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
@ -105,7 +102,7 @@ public:
void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2);
void SendHealth (void);
void SendRespawn(void);
void SendGameMode(char a_GameMode);
void SendGameMode(eGameMode a_GameMode);
void SendDestroyEntity(const cEntity & a_Entity);
void SendPlayerMoveLook(void);
void SendEntityStatus(const cEntity & a_Entity, char a_Status);
@ -138,7 +135,45 @@ public:
/// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
void AddWantedChunk(int a_ChunkX, int a_ChunkZ);
// Calls that cProtocol descendants use to report state:
void PacketBufferFull(void);
void PacketUnknown(unsigned char a_PacketType);
void PacketError(unsigned char a_PacketType);
// Calls that cProtocol descendants use for handling packets:
// Packets handled in csConnected:
void HandlePing (void);
void HandleHandshake (const AString & a_Username);
void HandleLogin (int a_ProtocolVersion, const AString & a_Username);
void HandleUnexpectedPacket(int a_PacketType); // the default case -> kick
// Packets handled while in csConfirmingPos:
void HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ); // While !m_bPositionConfirmed
// Packets handled while in csPlaying:
void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem);
void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);
void HandleBlockDig (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
void HandleBlockPlace (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
void HandleChat (const AString & a_Message);
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
void HandleAnimation (char a_Animation);
void HandleSlotSelected (short a_SlotNum);
void HandleWindowClose (char a_WindowID);
void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem);
void HandleUpdateSign (
int a_BlockX, int a_BlockY, int a_BlockZ,
const AString & a_Line1, const AString & a_Line2,
const AString & a_Line3, const AString & a_Line4
);
void HandleUseEntity (int a_TargetEntityID, bool a_IsLeftClick);
void HandleRespawn (void);
void HandleDisconnect (const AString & a_Reason);
void HandleKeepAlive (int a_KeepAliveID);
void SendData(const char * a_Data, int a_Size);
private:
int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
@ -148,25 +183,21 @@ private:
int m_ProtocolVersion;
AString m_Username;
AString m_Password;
cByteBuffer m_ReceivedData; // Accumulator for the data received from the socket, waiting to be parsed; accessed from the cSocketThreads' thread only!
cCriticalSection m_CSPackets;
PacketList m_PendingNrmSendPackets;
PacketList m_PendingLowSendPackets;
cCriticalSection m_CSChunkLists;
cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to
cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them)
cSocket m_Socket;
cSocket m_Socket;
cProtocol * m_Protocol;
cCriticalSection m_CSOutgoingData;
cByteBuffer m_OutgoingData;
cCriticalSection m_CriticalSection;
Vector3d m_ConfirmPosition;
cPacket * m_PacketMap[256];
bool m_bDestroyed;
cPlayer * m_Player;
bool m_bKicking;
@ -198,39 +229,6 @@ private:
bool m_bKeepThreadGoing;
void HandlePacket(cPacket * a_Packet);
// Packets handled in csConnected:
void HandlePing (void);
void HandleHandshake (const AString & a_Username);
void HandleLogin (int a_ProtocolVersion, const AString & a_Username);
void HandleUnexpectedPacket(int a_PacketType); // the default case -> kick
// Packets handled while in csConfirmingPos:
void HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ); // While !m_bPositionConfirmed
// Packets handled while in csPlaying:
void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem);
void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);
void HandleBlockDig (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
void HandleBlockPlace (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
void HandleChat (const AString & a_Message);
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
void HandleAnimation (char a_Animation);
void HandleSlotSelected (short a_SlotNum);
void HandleWindowClose (char a_WindowID);
void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem);
void HandleUpdateSign (
int a_BlockX, int a_BlockY, int a_BlockZ,
const AString & a_Line1, const AString & a_Line2,
const AString & a_Line3, const AString & a_Line4
);
void HandleUseEntity (int a_TargetEntityID, bool a_IsLeftClick);
void HandleRespawn (void);
void HandleDisconnect (const AString & a_Reason);
void HandleKeepAlive (int a_KeepAliveID);
/*
/// Handles rclk with a dye; returns true if the dye is to be be consumed
bool HandleDyes(cPacket_BlockPlace * a_Packet);

View File

@ -283,24 +283,6 @@ cServer::~cServer()
// TODO - Need to modify this or something, so it broadcasts to all worlds? And move this to cWorld?
void cServer::Broadcast(const cPacket & a_Packet, cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSClients);
for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr)
{
if ((*itr == a_Exclude) || !(*itr)->IsLoggedIn())
{
continue;
}
(*itr)->Send(a_Packet);
}
}
void cServer::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSClients);

View File

@ -38,7 +38,6 @@ public: //tolua_export
bool IsConnected(){return m_bIsConnected;} // returns connection status
void StartListenClient(); // Listen to client
void Broadcast(const cPacket & a_Packet, cClientHandle* a_Exclude = NULL);
void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL);
bool Tick(float a_Dt);

View File

@ -18,7 +18,6 @@
cSocketThreads::cSocketThreads(void)
{
LOG("cSocketThreads startup");
}
@ -55,7 +54,7 @@ bool cSocketThreads::AddClient(cSocket * a_Socket, cCallback * a_Client)
}
// No thread has free space, create a new one:
LOG("Creating a new cSocketThread (currently have %d)", m_Threads.size());
LOGD("Creating a new cSocketThread (currently have %d)", m_Threads.size());
cSocketThread * Thread = new cSocketThread(this);
if (!Thread->Start())
{

View File

@ -19,7 +19,7 @@ This means that the socket can be written to several times before finally closin
/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform)
/// How many clients should one thread handle? (must be less than FD_SETSIZE for your platform)
#define MAX_SLOTS 63
@ -38,7 +38,7 @@ This means that the socket can be written to several times before finally closin
// Check MAX_SLOTS:
#if MAX_SLOTS >= FD_SETSIZE
#error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)"
#error "MAX_SLOTS must be less than FD_SETSIZE for your platform! (otherwise select() won't work)"
#endif

View File

@ -92,8 +92,8 @@ private:
void Destroy();
int m_WindowID;
int m_WindowType;
char m_WindowID;
int m_WindowType;
AString m_WindowTitle;
cWindowOwner * m_Owner;

View File

@ -1213,41 +1213,6 @@ const double & cWorld::GetSpawnY(void)
void cWorld::Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
{
continue;
}
ch->Send( a_Packet );
}
}
void cWorld::BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Packet, a_Exclude);
}
void cWorld::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude);
}
void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude)
{
@ -1447,6 +1412,24 @@ void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer
void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
{
continue;
}
ch->SendPlayerListItem(a_Player, a_IsOnline);
}
}
void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Exclude);
@ -1767,7 +1750,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch != NULL) && !ch->IsDestroyed())
{
a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr));
a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), true);
}
}
}

View File

@ -25,7 +25,6 @@
class cPacket;
class cRedstone;
class cFireSimulator;
class cWaterSimulator;
@ -59,7 +58,7 @@ class cWorld //tolua_export
{ //tolua_export
public:
OBSOLETE static cWorld* GetWorld();
OBSOLETE static cWorld * GetWorld();
// Return time in seconds
inline static float GetTime() //tolua_export
@ -74,10 +73,6 @@ public:
int GetHeight( int a_X, int a_Z ); //tolua_export
void Broadcast(const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL);
void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
@ -96,6 +91,7 @@ public:
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL);
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL);
/// If there is a block entity at the specified coods, sends it to all clients except a_Exclude
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
@ -175,9 +171,6 @@ public:
void AddEntity( cEntity* a_Entity );
/// Add an entity to the chunk specified; broadcasts the a_SpawnPacket to all clients of that chunk
void AddEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket * a_SpawnPacket);
/// Removes the entity from the chunk specified
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);

View File

@ -9,9 +9,12 @@
#define PACKET_INCOMPLETE -2
#define PACKET_ERROR -1
#define PACKET_OK 1
enum
{
PACKET_INCOMPLETE = -2,
PACKET_ERROR = -1,
PACKET_OK = 1,
} ;

View File

@ -18,7 +18,7 @@ public:
cPacket_13()
: m_EntityID( 0 )
, m_ActionID( 0 )
{ m_PacketID = E_PACKET_13; }
{ m_PacketID = E_PACKET_ENTITY_ACTION; }
virtual cPacket* Clone() const { return new cPacket_13( *this ); }
virtual int Parse(cByteBuffer & a_Buffer) override;

View File

@ -202,15 +202,15 @@ void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPacket_PlayerPosition:
cPacket_PlayerPosition::cPacket_PlayerPosition(cPlayer * a_Player)
cPacket_PlayerPosition::cPacket_PlayerPosition(const cPlayer & a_Player)
{
m_PacketID = E_PLAYERPOS;
m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY();
m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance();
m_IsOnGround = a_Player->IsOnGround();
m_PosX = a_Player.GetPosX();
m_PosY = a_Player.GetPosY();
m_PosZ = a_Player.GetPosZ();
m_Stance = a_Player.GetStance();
m_IsOnGround = a_Player.IsOnGround();
}

View File

@ -131,7 +131,7 @@ public:
class cPacket_PlayerPosition : public cPacket
{
public:
cPacket_PlayerPosition( cPlayer* a_Player );
cPacket_PlayerPosition(const cPlayer & a_Player);
cPacket_PlayerPosition()
: m_PosX( 0.0 )
, m_PosY( 0.0 )