summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordImrich <damian@haze.sk>2021-02-04 00:33:17 +0100
committerTiger Wang <ziwei.tiger@outlook.com>2021-02-06 15:14:40 +0100
commit925f960ea2aeeea8eaeae94a8ef6602690b215c2 (patch)
treec865f2e046008670b8fc9e7985c8394a7590c97e
parentCreative mode hits immediately disappear boats (#5117) (diff)
downloadcuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar.gz
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar.bz2
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar.lz
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar.xz
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.tar.zst
cuberite-925f960ea2aeeea8eaeae94a8ef6602690b215c2.zip
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua30
-rw-r--r--Server/Plugins/APIDump/Classes/World.lua15
-rw-r--r--src/Blocks/BroadcastInterface.h1
-rw-r--r--src/Broadcaster.cpp13
-rw-r--r--src/ClientHandle.cpp9
-rw-r--r--src/ClientHandle.h1
-rw-r--r--src/Protocol/Packetizer.cpp151
-rw-r--r--src/Protocol/Protocol.h2
-rw-r--r--src/Protocol/Protocol_1_12.cpp61
-rw-r--r--src/Protocol/Protocol_1_13.cpp107
-rw-r--r--src/Protocol/Protocol_1_8.cpp160
-rw-r--r--src/Protocol/Protocol_1_8.h1
-rw-r--r--src/Protocol/Protocol_1_9.cpp160
-rw-r--r--src/Root.cpp12
-rw-r--r--src/Root.h3
-rw-r--r--src/World.h1
16 files changed, 417 insertions, 310 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index 88e999bd3..430e43df6 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -1584,6 +1584,21 @@ end
},
Notes = "Sends the specified animation of the specified entity to the client. The AnimationNumber is protocol-specific.",
},
+ SendPlayerListHeaderFooter =
+ {
+ Params =
+ {
+ {
+ Type = "cCompositeChat",
+ Name = "Header",
+ },
+ {
+ Type = "cCompositeChat",
+ Name = "Footer",
+ },
+ },
+ Desc = "Sends the header and footer of the player list to the client.",
+ },
SendHideTitle =
{
Notes = "Hides the title. This makes the title and subtitle disappear, but if you call SendTitleTimes() the same title and subtitle will appear again."
@@ -11388,6 +11403,21 @@ a_Player:OpenWindow(Window);
},
Notes = "Broadcasts the specified message to all players, with its message type set to mtWarning. Use for concerning events, such as plugin reload etc.",
},
+ BroadcastPlayerListsHeaderFooter =
+ {
+ Params =
+ {
+ {
+ Type = "cCompositeChat",
+ Name = "Header",
+ },
+ {
+ Type = "cCompositeChat",
+ Name = "Footer",
+ },
+ },
+ Desc = "Broadcasts the header and footer of the player list to all players.",
+ },
DoWithPlayerByUUID =
{
Params =
diff --git a/Server/Plugins/APIDump/Classes/World.lua b/Server/Plugins/APIDump/Classes/World.lua
index a1f2bc979..8792e7651 100644
--- a/Server/Plugins/APIDump/Classes/World.lua
+++ b/Server/Plugins/APIDump/Classes/World.lua
@@ -327,6 +327,21 @@ return
},
Notes = "Spawns the specified particles to all players in the world exept the optional ExeptClient. A list of available particles by thinkofdeath can be found {{https://gist.github.com/thinkofdeath/5110835|Here}}",
},
+ BroadcastPlayerListHeaderFooter =
+ {
+ Params =
+ {
+ {
+ Type = "cCompositeChat",
+ Name = "Header",
+ },
+ {
+ Type = "cCompositeChat",
+ Name = "Footer",
+ },
+ },
+ Desc = "Broadcasts the header and footer of the player list to all players in the world.",
+ },
BroadcastSoundEffect =
{
Params =
diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h
index ee903f461..93dbe4961 100644
--- a/src/Blocks/BroadcastInterface.h
+++ b/src/Blocks/BroadcastInterface.h
@@ -48,6 +48,7 @@ public:
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle * a_Exclude = nullptr) = 0;
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, const cClientHandle * a_Exclude = nullptr) = 0;
virtual void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
+ virtual void BroadcastPlayerListHeaderFooter (const cCompositeChat & a_Header, const cCompositeChat & a_Footer) = 0;
virtual void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
virtual void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
virtual void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
diff --git a/src/Broadcaster.cpp b/src/Broadcaster.cpp
index e7a29cb5d..98759a58b 100644
--- a/src/Broadcaster.cpp
+++ b/src/Broadcaster.cpp
@@ -418,6 +418,19 @@ void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClien
+void cWorld::BroadcastPlayerListHeaderFooter(const cCompositeChat & a_Header, const cCompositeChat & a_Footer)
+{
+ ForClientsInWorld(*this, nullptr, [&](cClientHandle & a_Client)
+ {
+ a_Client.SendPlayerListHeaderFooter(a_Header, a_Footer);
+ }
+ );
+}
+
+
+
+
+
void cWorld::BroadcastPlayerListRemovePlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude)
{
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 9d236e4d5..3c003e132 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -2625,6 +2625,15 @@ void cClientHandle::SendPlayerListAddPlayer(const cPlayer & a_Player)
+void cClientHandle::SendPlayerListHeaderFooter(const cCompositeChat & a_Header, const cCompositeChat & a_Footer)
+{
+ m_Protocol->SendPlayerListHeaderFooter(a_Header, a_Footer);
+}
+
+
+
+
+
void cClientHandle::SendPlayerListRemovePlayer(const cPlayer & a_Player)
{
m_Protocol->SendPlayerListRemovePlayer(a_Player);
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 2662f20d6..f3e0e7f25 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -183,6 +183,7 @@ public: // tolua_export
void SendParticleEffect (const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data);
void SendPlayerAbilities (void);
void SendPlayerListAddPlayer (const cPlayer & a_Player);
+ void SendPlayerListHeaderFooter (const cCompositeChat & a_Header, const cCompositeChat & a_Footer); // tolua_export
void SendPlayerListRemovePlayer (const cPlayer & a_Player);
void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName);
void SendPlayerListUpdateGameMode (const cPlayer & a_Player);
diff --git a/src/Protocol/Packetizer.cpp b/src/Protocol/Packetizer.cpp
index 12bfcc0dd..9f0fd28b1 100644
--- a/src/Protocol/Packetizer.cpp
+++ b/src/Protocol/Packetizer.cpp
@@ -57,81 +57,82 @@ AString cPacketizer::PacketTypeToStr(cProtocol::ePacketType a_PacketType)
{
switch (a_PacketType)
{
- case cProtocol::pktAttachEntity: return "pktAttachEntity";
- case cProtocol::pktBlockAction: return "pktBlockAction";
- case cProtocol::pktBlockBreakAnim: return "pktBlockBreakAnim";
- case cProtocol::pktBlockChange: return "pktBlockChange";
- case cProtocol::pktBlockChanges: return "pktBlockChanges";
- case cProtocol::pktCameraSetTo: return "pktCameraSetTo";
- case cProtocol::pktChatRaw: return "pktChatRaw";
- case cProtocol::pktCollectEntity: return "pktCollectEntity";
- case cProtocol::pktDestroyEntity: return "pktDestroyEntity";
- case cProtocol::pktDifficulty: return "pktDifficulty";
- case cProtocol::pktDisconnectDuringLogin: return "pktDisconnectDuringLogin";
- case cProtocol::pktDisconnectDuringGame: return "pktDisconnectDuringGame";
- case cProtocol::pktDisplayObjective: return "pktDisplayObjective";
- case cProtocol::pktEditSign: return "pktEditSign";
- case cProtocol::pktEncryptionRequest: return "pktEncryptionRequest";
- case cProtocol::pktEntityAnimation: return "pktEntityAnimation";
- case cProtocol::pktEntityEffect: return "pktEntityEffect";
- case cProtocol::pktEntityEquipment: return "pktEntityEquipment";
- case cProtocol::pktEntityHeadLook: return "pktEntityHeadLook";
- case cProtocol::pktEntityLook: return "pktEntityLook";
- case cProtocol::pktEntityMeta: return "pktEntityMeta";
- case cProtocol::pktEntityProperties: return "pktEntityProperties";
- case cProtocol::pktEntityRelMove: return "pktEntityRelMove";
- case cProtocol::pktEntityRelMoveLook: return "pktEntityRelMoveLook";
- case cProtocol::pktEntityStatus: return "pktEntityStatus";
- case cProtocol::pktEntityVelocity: return "pktEntityVelocity";
- case cProtocol::pktExperience: return "pktExperience";
- case cProtocol::pktExplosion: return "pktExplosion";
- case cProtocol::pktGameMode: return "pktGameMode";
- case cProtocol::pktHeldItemChange: return "pktHeldItemChange";
- case cProtocol::pktInventorySlot: return "pktInventorySlot";
- case cProtocol::pktJoinGame: return "pktJoinGame";
- case cProtocol::pktKeepAlive: return "pktKeepAlive";
- case cProtocol::pktLeashEntity: return "pktLeashEntity";
- case cProtocol::pktLoginSuccess: return "pktLoginSuccess";
- case cProtocol::pktMapData: return "pktMapData";
- case cProtocol::pktParticleEffect: return "pktParticleEffect";
- case cProtocol::pktPingResponse: return "pktPingResponse";
- case cProtocol::pktPlayerAbilities: return "pktPlayerAbilities";
- case cProtocol::pktPlayerList: return "pktPlayerList";
- case cProtocol::pktPlayerMaxSpeed: return "pktPlayerMaxSpeed";
- case cProtocol::pktPlayerMoveLook: return "pktPlayerMoveLook";
- case cProtocol::pktPluginMessage: return "pktPluginMessage";
- case cProtocol::pktRemoveEntityEffect: return "pktRemoveEntityEffect";
- case cProtocol::pktResourcePack: return "pktResourcePack";
- case cProtocol::pktRespawn: return "pktRespawn";
- case cProtocol::pktScoreboardObjective: return "pktScoreboardObjective";
- case cProtocol::pktSpawnObject: return "pktSpawnObject";
- case cProtocol::pktSoundEffect: return "pktSoundEffect";
- case cProtocol::pktSoundParticleEffect: return "pktSoundParticleEffect";
- case cProtocol::pktSpawnExperienceOrb: return "pktSpawnExperienceOrb";
- case cProtocol::pktSpawnGlobalEntity: return "pktSpawnGlobalEntity";
- case cProtocol::pktSpawnMob: return "pktSpawnMob";
- case cProtocol::pktSpawnOtherPlayer: return "pktSpawnOtherPlayer";
- case cProtocol::pktSpawnPainting: return "pktSpawnPainting";
- case cProtocol::pktSpawnPosition: return "pktSpawnPosition";
- case cProtocol::pktStartCompression: return "pktStartCompression";
- case cProtocol::pktStatistics: return "pktStatistics";
- case cProtocol::pktStatusResponse: return "pktStatusResponse";
- case cProtocol::pktTabCompletionResults: return "pktTabCompletionResults";
- case cProtocol::pktTeleportEntity: return "pktTeleportEntity";
- case cProtocol::pktTimeUpdate: return "pktTimeUpdate";
- case cProtocol::pktTitle: return "pktTitle";
- case cProtocol::pktUnloadChunk: return "pktUnloadChunk";
- case cProtocol::pktUnlockRecipe: return "pktUnlockRecipe";
- case cProtocol::pktUpdateBlockEntity: return "pktUpdateBlockEntity";
- case cProtocol::pktUpdateHealth: return "pktUpdateHealth";
- case cProtocol::pktUpdateScore: return "pktUpdateScore";
- case cProtocol::pktUpdateSign: return "pktUpdateSign";
- case cProtocol::pktUseBed: return "pktUseBed";
- case cProtocol::pktWeather: return "pktWeather";
- case cProtocol::pktWindowItems: return "pktWindowItems";
- case cProtocol::pktWindowClose: return "pktWindowClose";
- case cProtocol::pktWindowOpen: return "pktWindowOpen";
- case cProtocol::pktWindowProperty: return "pktWindowProperty";
+ case cProtocol::pktAttachEntity: return "pktAttachEntity";
+ case cProtocol::pktBlockAction: return "pktBlockAction";
+ case cProtocol::pktBlockBreakAnim: return "pktBlockBreakAnim";
+ case cProtocol::pktBlockChange: return "pktBlockChange";
+ case cProtocol::pktBlockChanges: return "pktBlockChanges";
+ case cProtocol::pktCameraSetTo: return "pktCameraSetTo";
+ case cProtocol::pktChatRaw: return "pktChatRaw";
+ case cProtocol::pktCollectEntity: return "pktCollectEntity";
+ case cProtocol::pktDestroyEntity: return "pktDestroyEntity";
+ case cProtocol::pktDifficulty: return "pktDifficulty";
+ case cProtocol::pktDisconnectDuringLogin: return "pktDisconnectDuringLogin";
+ case cProtocol::pktDisconnectDuringGame: return "pktDisconnectDuringGame";
+ case cProtocol::pktDisplayObjective: return "pktDisplayObjective";
+ case cProtocol::pktEditSign: return "pktEditSign";
+ case cProtocol::pktEncryptionRequest: return "pktEncryptionRequest";
+ case cProtocol::pktEntityAnimation: return "pktEntityAnimation";
+ case cProtocol::pktEntityEffect: return "pktEntityEffect";
+ case cProtocol::pktEntityEquipment: return "pktEntityEquipment";
+ case cProtocol::pktEntityHeadLook: return "pktEntityHeadLook";
+ case cProtocol::pktEntityLook: return "pktEntityLook";
+ case cProtocol::pktEntityMeta: return "pktEntityMeta";
+ case cProtocol::pktEntityProperties: return "pktEntityProperties";
+ case cProtocol::pktEntityRelMove: return "pktEntityRelMove";
+ case cProtocol::pktEntityRelMoveLook: return "pktEntityRelMoveLook";
+ case cProtocol::pktEntityStatus: return "pktEntityStatus";
+ case cProtocol::pktEntityVelocity: return "pktEntityVelocity";
+ case cProtocol::pktExperience: return "pktExperience";
+ case cProtocol::pktExplosion: return "pktExplosion";
+ case cProtocol::pktGameMode: return "pktGameMode";
+ case cProtocol::pktHeldItemChange: return "pktHeldItemChange";
+ case cProtocol::pktInventorySlot: return "pktInventorySlot";
+ case cProtocol::pktJoinGame: return "pktJoinGame";
+ case cProtocol::pktKeepAlive: return "pktKeepAlive";
+ case cProtocol::pktLeashEntity: return "pktLeashEntity";
+ case cProtocol::pktLoginSuccess: return "pktLoginSuccess";
+ case cProtocol::pktMapData: return "pktMapData";
+ case cProtocol::pktParticleEffect: return "pktParticleEffect";
+ case cProtocol::pktPingResponse: return "pktPingResponse";
+ case cProtocol::pktPlayerAbilities: return "pktPlayerAbilities";
+ case cProtocol::pktPlayerList: return "pktPlayerList";
+ case cProtocol::pktPlayerListHeaderFooter: return "pktPlayerListHeaderFooter";
+ case cProtocol::pktPlayerMaxSpeed: return "pktPlayerMaxSpeed";
+ case cProtocol::pktPlayerMoveLook: return "pktPlayerMoveLook";
+ case cProtocol::pktPluginMessage: return "pktPluginMessage";
+ case cProtocol::pktRemoveEntityEffect: return "pktRemoveEntityEffect";
+ case cProtocol::pktResourcePack: return "pktResourcePack";
+ case cProtocol::pktRespawn: return "pktRespawn";
+ case cProtocol::pktScoreboardObjective: return "pktScoreboardObjective";
+ case cProtocol::pktSpawnObject: return "pktSpawnObject";
+ case cProtocol::pktSoundEffect: return "pktSoundEffect";
+ case cProtocol::pktSoundParticleEffect: return "pktSoundParticleEffect";
+ case cProtocol::pktSpawnExperienceOrb: return "pktSpawnExperienceOrb";
+ case cProtocol::pktSpawnGlobalEntity: return "pktSpawnGlobalEntity";
+ case cProtocol::pktSpawnMob: return "pktSpawnMob";
+ case cProtocol::pktSpawnOtherPlayer: return "pktSpawnOtherPlayer";
+ case cProtocol::pktSpawnPainting: return "pktSpawnPainting";
+ case cProtocol::pktSpawnPosition: return "pktSpawnPosition";
+ case cProtocol::pktStartCompression: return "pktStartCompression";
+ case cProtocol::pktStatistics: return "pktStatistics";
+ case cProtocol::pktStatusResponse: return "pktStatusResponse";
+ case cProtocol::pktTabCompletionResults: return "pktTabCompletionResults";
+ case cProtocol::pktTeleportEntity: return "pktTeleportEntity";
+ case cProtocol::pktTimeUpdate: return "pktTimeUpdate";
+ case cProtocol::pktTitle: return "pktTitle";
+ case cProtocol::pktUnloadChunk: return "pktUnloadChunk";
+ case cProtocol::pktUnlockRecipe: return "pktUnlockRecipe";
+ case cProtocol::pktUpdateBlockEntity: return "pktUpdateBlockEntity";
+ case cProtocol::pktUpdateHealth: return "pktUpdateHealth";
+ case cProtocol::pktUpdateScore: return "pktUpdateScore";
+ case cProtocol::pktUpdateSign: return "pktUpdateSign";
+ case cProtocol::pktUseBed: return "pktUseBed";
+ case cProtocol::pktWeather: return "pktWeather";
+ case cProtocol::pktWindowItems: return "pktWindowItems";
+ case cProtocol::pktWindowClose: return "pktWindowClose";
+ case cProtocol::pktWindowOpen: return "pktWindowOpen";
+ case cProtocol::pktWindowProperty: return "pktWindowProperty";
}
return Printf("Unknown packet type: 0x%02x", a_PacketType);
}
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index 341e0b0f4..7b5ad7a51 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -102,6 +102,7 @@ public:
pktPingResponse,
pktPlayerAbilities,
pktPlayerList,
+ pktPlayerListHeaderFooter,
pktPlayerMaxSpeed,
pktPlayerMoveLook,
pktPluginMessage,
@@ -397,6 +398,7 @@ public:
virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0;
virtual void SendParticleEffect (const AString & a_SoundName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) = 0;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) = 0;
+ virtual void SendPlayerListHeaderFooter (const cCompositeChat & a_Header, const cCompositeChat & a_Footer) = 0;
virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) = 0;
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0;
virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) = 0;
diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp
index 30a975d18..e4ce9a942 100644
--- a/src/Protocol/Protocol_1_12.cpp
+++ b/src/Protocol/Protocol_1_12.cpp
@@ -1167,36 +1167,37 @@ UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet)
{
switch (a_Packet)
{
- case pktAttachEntity: return 0x43;
- case pktCameraSetTo: return 0x39;
- case pktCollectEntity: return 0x4b;
- case pktDestroyEntity: return 0x32;
- case pktDisplayObjective: return 0x3b;
- case pktEntityEffect: return 0x4f;
- case pktEntityEquipment: return 0x3f;
- case pktEntityHeadLook: return 0x36;
- case pktEntityMeta: return 0x3c;
- case pktEntityProperties: return 0x4e;
- case pktEntityVelocity: return 0x3e;
- case pktExperience: return 0x40;
- case pktHeldItemChange: return 0x3a;
- case pktLeashEntity: return 0x3d;
- case pktPlayerList: return 0x2e;
- case pktPlayerAbilities: return 0x2c;
- case pktPlayerMaxSpeed: return 0x4e;
- case pktPlayerMoveLook: return 0x2f;
- case pktRemoveEntityEffect: return 0x33;
- case pktResourcePack: return 0x34;
- case pktRespawn: return 0x35;
- case pktScoreboardObjective: return 0x42;
- case pktSpawnPosition: return 0x46;
- case pktUnlockRecipe: return 0x31;
- case pktUpdateHealth: return 0x41;
- case pktUpdateScore: return 0x45;
- case pktUseBed: return 0x30;
- case pktTeleportEntity: return 0x4c;
- case pktTimeUpdate: return 0x47;
- case pktTitle: return 0x48;
+ case pktAttachEntity: return 0x43;
+ case pktCameraSetTo: return 0x39;
+ case pktCollectEntity: return 0x4b;
+ case pktDestroyEntity: return 0x32;
+ case pktDisplayObjective: return 0x3b;
+ case pktEntityEffect: return 0x4f;
+ case pktEntityEquipment: return 0x3f;
+ case pktEntityHeadLook: return 0x36;
+ case pktEntityMeta: return 0x3c;
+ case pktEntityProperties: return 0x4e;
+ case pktEntityVelocity: return 0x3e;
+ case pktExperience: return 0x40;
+ case pktHeldItemChange: return 0x3a;
+ case pktLeashEntity: return 0x3d;
+ case pktPlayerList: return 0x2e;
+ case pktPlayerListHeaderFooter: return 0x4a;
+ case pktPlayerAbilities: return 0x2c;
+ case pktPlayerMaxSpeed: return 0x4e;
+ case pktPlayerMoveLook: return 0x2f;
+ case pktRemoveEntityEffect: return 0x33;
+ case pktResourcePack: return 0x34;
+ case pktRespawn: return 0x35;
+ case pktScoreboardObjective: return 0x42;
+ case pktSpawnPosition: return 0x46;
+ case pktUnlockRecipe: return 0x31;
+ case pktUpdateHealth: return 0x41;
+ case pktUpdateScore: return 0x45;
+ case pktUseBed: return 0x30;
+ case pktTeleportEntity: return 0x4c;
+ case pktTimeUpdate: return 0x47;
+ case pktTitle: return 0x48;
default: return Super::GetPacketID(a_Packet);
}
diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp
index 4da065af7..dbfd51d59 100644
--- a/src/Protocol/Protocol_1_13.cpp
+++ b/src/Protocol/Protocol_1_13.cpp
@@ -337,59 +337,60 @@ UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
{
switch (a_PacketType)
{
- case pktAttachEntity: return 0x46;
- case pktBlockChanges: return 0x0f;
- case pktCameraSetTo: return 0x3c;
- case pktChatRaw: return 0x0e;
- case pktCollectEntity: return 0x4f;
- case pktDestroyEntity: return 0x35;
- case pktDisconnectDuringGame: return 0x1b;
- case pktEditSign: return 0x2c;
- case pktEntityEffect: return 0x53;
- case pktEntityEquipment: return 0x42;
- case pktEntityHeadLook: return 0x39;
- case pktEntityLook: return 0x2a;
- case pktEntityMeta: return 0x3f;
- case pktEntityProperties: return 0x52;
- case pktEntityRelMove: return 0x28;
- case pktEntityRelMoveLook: return 0x29;
- case pktEntityStatus: return 0x1c;
- case pktEntityVelocity: return 0x41;
- case pktExperience: return 0x43;
- case pktExplosion: return 0x1e;
- case pktGameMode: return 0x20;
- case pktHeldItemChange: return 0x3d;
- case pktInventorySlot: return 0x17;
- case pktJoinGame: return 0x25;
- case pktKeepAlive: return 0x21;
- case pktLeashEntity: return 0x40;
- case pktMapData: return 0x26;
- case pktParticleEffect: return 0x24;
- case pktPlayerAbilities: return 0x2e;
- case pktPlayerList: return 0x30;
- case pktPlayerMaxSpeed: return 0x52;
- case pktPlayerMoveLook: return 0x32;
- case pktPluginMessage: return 0x19;
- case pktRemoveEntityEffect: return 0x36;
- case pktRespawn: return 0x38;
- case pktScoreboardObjective: return 0x45;
- case pktSoundEffect: return 0x1a;
- case pktSoundParticleEffect: return 0x23;
- case pktSpawnPosition: return 0x49;
- case pktTabCompletionResults: return 0x10;
- case pktTeleportEntity: return 0x50;
- case pktTimeUpdate: return 0x4a;
- case pktTitle: return 0x4b;
- case pktUnloadChunk: return 0x1f;
- case pktUnlockRecipe: return 0x32;
- case pktUpdateHealth: return 0x44;
- case pktUpdateScore: return 0x48;
- case pktUpdateSign: return GetPacketID(pktUpdateBlockEntity);
- case pktUseBed: return 0x33;
- case pktWindowClose: return 0x13;
- case pktWindowItems: return 0x15;
- case pktWindowOpen: return 0x14;
- case pktWindowProperty: return 0x16;
+ case pktAttachEntity: return 0x46;
+ case pktBlockChanges: return 0x0f;
+ case pktCameraSetTo: return 0x3c;
+ case pktChatRaw: return 0x0e;
+ case pktCollectEntity: return 0x4f;
+ case pktDestroyEntity: return 0x35;
+ case pktDisconnectDuringGame: return 0x1b;
+ case pktEditSign: return 0x2c;
+ case pktEntityEffect: return 0x53;
+ case pktEntityEquipment: return 0x42;
+ case pktEntityHeadLook: return 0x39;
+ case pktEntityLook: return 0x2a;
+ case pktEntityMeta: return 0x3f;
+ case pktEntityProperties: return 0x52;
+ case pktEntityRelMove: return 0x28;
+ case pktEntityRelMoveLook: return 0x29;
+ case pktEntityStatus: return 0x1c;
+ case pktEntityVelocity: return 0x41;
+ case pktExperience: return 0x43;
+ case pktExplosion: return 0x1e;
+ case pktGameMode: return 0x20;
+ case pktHeldItemChange: return 0x3d;
+ case pktInventorySlot: return 0x17;
+ case pktJoinGame: return 0x25;
+ case pktKeepAlive: return 0x21;
+ case pktLeashEntity: return 0x40;
+ case pktMapData: return 0x26;
+ case pktParticleEffect: return 0x24;
+ case pktPlayerAbilities: return 0x2e;
+ case pktPlayerList: return 0x30;
+ case pktPlayerListHeaderFooter: return 0x4E;
+ case pktPlayerMaxSpeed: return 0x52;
+ case pktPlayerMoveLook: return 0x32;
+ case pktPluginMessage: return 0x19;
+ case pktRemoveEntityEffect: return 0x36;
+ case pktRespawn: return 0x38;
+ case pktScoreboardObjective: return 0x45;
+ case pktSoundEffect: return 0x1a;
+ case pktSoundParticleEffect: return 0x23;
+ case pktSpawnPosition: return 0x49;
+ case pktTabCompletionResults: return 0x10;
+ case pktTeleportEntity: return 0x50;
+ case pktTimeUpdate: return 0x4a;
+ case pktTitle: return 0x4b;
+ case pktUnloadChunk: return 0x1f;
+ case pktUnlockRecipe: return 0x32;
+ case pktUpdateHealth: return 0x44;
+ case pktUpdateScore: return 0x48;
+ case pktUpdateSign: return GetPacketID(pktUpdateBlockEntity);
+ case pktUseBed: return 0x33;
+ case pktWindowClose: return 0x13;
+ case pktWindowItems: return 0x15;
+ case pktWindowOpen: return 0x14;
+ case pktWindowProperty: return 0x16;
default: return Super::GetPacketID(a_PacketType);
}
}
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index cafcfb0ff..003fc75e2 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -994,6 +994,19 @@ void cProtocol_1_8_0::SendPlayerListAddPlayer(const cPlayer & a_Player)
+void cProtocol_1_8_0::SendPlayerListHeaderFooter(const cCompositeChat & a_Header, const cCompositeChat & a_Footer)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, pktPlayerListHeaderFooter);
+ Pkt.WriteString(a_Header.CreateJsonString(false));
+ Pkt.WriteString(a_Footer.CreateJsonString(false));
+}
+
+
+
+
+
void cProtocol_1_8_0::SendPlayerListRemovePlayer(const cPlayer & a_Player)
{
ASSERT(m_State == 3); // In game mode?
@@ -2043,79 +2056,80 @@ UInt32 cProtocol_1_8_0::GetPacketID(ePacketType a_PacketType)
{
switch (a_PacketType)
{
- case pktAttachEntity: return 0x1b;
- case pktBlockAction: return 0x24;
- case pktBlockBreakAnim: return 0x25;
- case pktBlockChange: return 0x23;
- case pktBlockChanges: return 0x22;
- case pktCameraSetTo: return 0x43;
- case pktChatRaw: return 0x02;
- case pktCollectEntity: return 0x0d;
- case pktDestroyEntity: return 0x13;
- case pktDifficulty: return 0x41;
- case pktDisconnectDuringGame: return 0x40;
- case pktDisconnectDuringLogin: return 0x00;
- case pktDisplayObjective: return 0x3d;
- case pktEditSign: return 0x36;
- case pktEncryptionRequest: return 0x01;
- case pktEntityAnimation: return 0x0b;
- case pktEntityEffect: return 0x1d;
- case pktEntityEquipment: return 0x04;
- case pktEntityHeadLook: return 0x19;
- case pktEntityLook: return 0x16;
- case pktEntityMeta: return 0x1c;
- case pktEntityProperties: return 0x20;
- case pktEntityRelMove: return 0x15;
- case pktEntityRelMoveLook: return 0x17;
- case pktEntityStatus: return 0x1a;
- case pktEntityVelocity: return 0x12;
- case pktExperience: return 0x1f;
- case pktExplosion: return 0x27;
- case pktGameMode: return 0x2b;
- case pktHeldItemChange: return 0x09;
- case pktInventorySlot: return 0x2f;
- case pktJoinGame: return 0x01;
- case pktKeepAlive: return 0x00;
- case pktLeashEntity: return 0x1b;
- case pktLoginSuccess: return 0x02;
- case pktMapData: return 0x34;
- case pktParticleEffect: return 0x2a;
- case pktPingResponse: return 0x01;
- case pktPlayerAbilities: return 0x39;
- case pktPlayerList: return 0x38;
- case pktPlayerMoveLook: return 0x08;
- case pktPluginMessage: return 0x3f;
- case pktRemoveEntityEffect: return 0x1e;
- case pktResourcePack: return 0x48;
- case pktRespawn: return 0x07;
- case pktScoreboardObjective: return 0x3b;
- case pktSoundEffect: return 0x29;
- case pktSoundParticleEffect: return 0x28;
- case pktSpawnExperienceOrb: return 0x11;
- case pktSpawnGlobalEntity: return 0x2c;
- case pktSpawnMob: return 0x0f;
- case pktSpawnObject: return 0x0e;
- case pktSpawnOtherPlayer: return 0x0c;
- case pktSpawnPainting: return 0x10;
- case pktSpawnPosition: return 0x05;
- case pktStartCompression: return 0x03;
- case pktStatistics: return 0x37;
- case pktStatusResponse: return 0x00;
- case pktTabCompletionResults: return 0x3a;
- case pktTeleportEntity: return 0x18;
- case pktTimeUpdate: return 0x03;
- case pktTitle: return 0x45;
- case pktUnloadChunk: return 0x21;
- case pktUpdateBlockEntity: return 0x35;
- case pktUpdateHealth: return 0x06;
- case pktUpdateScore: return 0x3c;
- case pktUpdateSign: return 0x33;
- case pktUseBed: return 0x0a;
- case pktWeather: return 0x2b;
- case pktWindowClose: return 0x2e;
- case pktWindowItems: return 0x30;
- case pktWindowOpen: return 0x2d;
- case pktWindowProperty: return 0x31;
+ case pktAttachEntity: return 0x1b;
+ case pktBlockAction: return 0x24;
+ case pktBlockBreakAnim: return 0x25;
+ case pktBlockChange: return 0x23;
+ case pktBlockChanges: return 0x22;
+ case pktCameraSetTo: return 0x43;
+ case pktChatRaw: return 0x02;
+ case pktCollectEntity: return 0x0d;
+ case pktDestroyEntity: return 0x13;
+ case pktDifficulty: return 0x41;
+ case pktDisconnectDuringGame: return 0x40;
+ case pktDisconnectDuringLogin: return 0x00;
+ case pktDisplayObjective: return 0x3d;
+ case pktEditSign: return 0x36;
+ case pktEncryptionRequest: return 0x01;
+ case pktEntityAnimation: return 0x0b;
+ case pktEntityEffect: return 0x1d;
+ case pktEntityEquipment: return 0x04;
+ case pktEntityHeadLook: return 0x19;
+ case pktEntityLook: return 0x16;
+ case pktEntityMeta: return 0x1c;
+ case pktEntityProperties: return 0x20;
+ case pktEntityRelMove: return 0x15;
+ case pktEntityRelMoveLook: return 0x17;
+ case pktEntityStatus: return 0x1a;
+ case pktEntityVelocity: return 0x12;
+ case pktExperience: return 0x1f;
+ case pktExplosion: return 0x27;
+ case pktGameMode: return 0x2b;
+ case pktHeldItemChange: return 0x09;
+ case pktInventorySlot: return 0x2f;
+ case pktJoinGame: return 0x01;
+ case pktKeepAlive: return 0x00;
+ case pktLeashEntity: return 0x1b;
+ case pktLoginSuccess: return 0x02;
+ case pktMapData: return 0x34;
+ case pktParticleEffect: return 0x2a;
+ case pktPingResponse: return 0x01;
+ case pktPlayerAbilities: return 0x39;
+ case pktPlayerList: return 0x38;
+ case pktPlayerListHeaderFooter: return 0x47;
+ case pktPlayerMoveLook: return 0x08;
+ case pktPluginMessage: return 0x3f;
+ case pktRemoveEntityEffect: return 0x1e;
+ case pktResourcePack: return 0x48;
+ case pktRespawn: return 0x07;
+ case pktScoreboardObjective: return 0x3b;
+ case pktSoundEffect: return 0x29;
+ case pktSoundParticleEffect: return 0x28;
+ case pktSpawnExperienceOrb: return 0x11;
+ case pktSpawnGlobalEntity: return 0x2c;
+ case pktSpawnMob: return 0x0f;
+ case pktSpawnObject: return 0x0e;
+ case pktSpawnOtherPlayer: return 0x0c;
+ case pktSpawnPainting: return 0x10;
+ case pktSpawnPosition: return 0x05;
+ case pktStartCompression: return 0x03;
+ case pktStatistics: return 0x37;
+ case pktStatusResponse: return 0x00;
+ case pktTabCompletionResults: return 0x3a;
+ case pktTeleportEntity: return 0x18;
+ case pktTimeUpdate: return 0x03;
+ case pktTitle: return 0x45;
+ case pktUnloadChunk: return 0x21;
+ case pktUpdateBlockEntity: return 0x35;
+ case pktUpdateHealth: return 0x06;
+ case pktUpdateScore: return 0x3c;
+ case pktUpdateSign: return 0x33;
+ case pktUseBed: return 0x0a;
+ case pktWeather: return 0x2b;
+ case pktWindowClose: return 0x2e;
+ case pktWindowItems: return 0x30;
+ case pktWindowOpen: return 0x2d;
+ case pktWindowProperty: return 0x31;
default:
{
LOG("Unhandled outgoing packet type: %s (0x%02x)", cPacketizer::PacketTypeToStr(a_PacketType), a_PacketType);
diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h
index f5800cb21..4e4f2fa47 100644
--- a/src/Protocol/Protocol_1_8.h
+++ b/src/Protocol/Protocol_1_8.h
@@ -83,6 +83,7 @@ public:
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override;
virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
+ virtual void SendPlayerListHeaderFooter (const cCompositeChat & a_Header, const cCompositeChat & a_Footer) override;
virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override;
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override;
virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override;
diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp
index 67e920925..e2396ce0e 100644
--- a/src/Protocol/Protocol_1_9.cpp
+++ b/src/Protocol/Protocol_1_9.cpp
@@ -483,80 +483,81 @@ UInt32 cProtocol_1_9_0::GetPacketID(cProtocol::ePacketType a_Packet)
{
switch (a_Packet)
{
- case pktAttachEntity: return 0x40;
- case pktBlockAction: return 0x0a;
- case pktBlockBreakAnim: return 0x08;
- case pktBlockChange: return 0x0b;
- case pktBlockChanges: return 0x10;
- case pktCameraSetTo: return 0x36;
- case pktChatRaw: return 0x0f;
- case pktCollectEntity: return 0x49;
- case pktDestroyEntity: return 0x30;
- case pktDifficulty: return 0x0d;
- case pktDisconnectDuringGame: return 0x1a;
- case pktDisconnectDuringLogin: return 0x0;
- case pktDisplayObjective: return 0x38;
- case pktEditSign: return 0x2a;
- case pktEncryptionRequest: return 0x01;
- case pktEntityAnimation: return 0x06;
- case pktEntityEffect: return 0x4c;
- case pktEntityEquipment: return 0x3c;
- case pktEntityHeadLook: return 0x34;
- case pktEntityLook: return 0x27;
- case pktEntityMeta: return 0x39;
- case pktEntityProperties: return 0x4b;
- case pktEntityRelMove: return 0x25;
- case pktEntityRelMoveLook: return 0x26;
- case pktEntityStatus: return 0x1b;
- case pktEntityVelocity: return 0x3b;
- case pktExperience: return 0x3d;
- case pktExplosion: return 0x1c;
- case pktGameMode: return 0x1e;
- case pktHeldItemChange: return 0x37;
- case pktInventorySlot: return 0x16;
- case pktJoinGame: return 0x23;
- case pktKeepAlive: return 0x1f;
- case pktLeashEntity: return 0x3a;
- case pktLoginSuccess: return 0x02;
- case pktMapData: return 0x24;
- case pktParticleEffect: return 0x22;
- case pktPingResponse: return 0x01;
- case pktPlayerAbilities: return 0x2b;
- case pktPlayerList: return 0x2d;
- case pktPlayerMaxSpeed: return 0x4b;
- case pktPlayerMoveLook: return 0x2e;
- case pktPluginMessage: return 0x18;
- case pktRemoveEntityEffect: return 0x31;
- case pktResourcePack: return 0x32;
- case pktRespawn: return 0x33;
- case pktScoreboardObjective: return 0x3f;
- case pktSpawnExperienceOrb: return 0x01;
- case pktSpawnGlobalEntity: return 0x02;
- case pktSpawnObject: return 0x00;
- case pktSpawnOtherPlayer: return 0x05;
- case pktSpawnPainting: return 0x04;
- case pktSpawnPosition: return 0x43;
- case pktSoundEffect: return 0x19;
- case pktSoundParticleEffect: return 0x21;
- case pktSpawnMob: return 0x03;
- case pktStartCompression: return 0x03;
- case pktStatistics: return 0x07;
- case pktStatusResponse: return 0x00;
- case pktTabCompletionResults: return 0x0e;
- case pktTeleportEntity: return 0x4a;
- case pktTimeUpdate: return 0x44;
- case pktTitle: return 0x45;
- case pktUnloadChunk: return 0x1d;
- case pktUpdateBlockEntity: return 0x09;
- case pktUpdateHealth: return 0x3e;
- case pktUpdateScore: return 0x42;
- case pktUpdateSign: return 0x46;
- case pktUseBed: return 0x2f;
- case pktWeather: return 0x1e;
- case pktWindowClose: return 0x12;
- case pktWindowItems: return 0x14;
- case pktWindowOpen: return 0x13;
- case pktWindowProperty: return 0x15;
+ case pktAttachEntity: return 0x40;
+ case pktBlockAction: return 0x0a;
+ case pktBlockBreakAnim: return 0x08;
+ case pktBlockChange: return 0x0b;
+ case pktBlockChanges: return 0x10;
+ case pktCameraSetTo: return 0x36;
+ case pktChatRaw: return 0x0f;
+ case pktCollectEntity: return 0x49;
+ case pktDestroyEntity: return 0x30;
+ case pktDifficulty: return 0x0d;
+ case pktDisconnectDuringGame: return 0x1a;
+ case pktDisconnectDuringLogin: return 0x0;
+ case pktDisplayObjective: return 0x38;
+ case pktEditSign: return 0x2a;
+ case pktEncryptionRequest: return 0x01;
+ case pktEntityAnimation: return 0x06;
+ case pktEntityEffect: return 0x4c;
+ case pktEntityEquipment: return 0x3c;
+ case pktEntityHeadLook: return 0x34;
+ case pktEntityLook: return 0x27;
+ case pktEntityMeta: return 0x39;
+ case pktEntityProperties: return 0x4b;
+ case pktEntityRelMove: return 0x25;
+ case pktEntityRelMoveLook: return 0x26;
+ case pktEntityStatus: return 0x1b;
+ case pktEntityVelocity: return 0x3b;
+ case pktExperience: return 0x3d;
+ case pktExplosion: return 0x1c;
+ case pktGameMode: return 0x1e;
+ case pktHeldItemChange: return 0x37;
+ case pktInventorySlot: return 0x16;
+ case pktJoinGame: return 0x23;
+ case pktKeepAlive: return 0x1f;
+ case pktLeashEntity: return 0x3a;
+ case pktLoginSuccess: return 0x02;
+ case pktMapData: return 0x24;
+ case pktParticleEffect: return 0x22;
+ case pktPingResponse: return 0x01;
+ case pktPlayerAbilities: return 0x2b;
+ case pktPlayerList: return 0x2d;
+ case pktPlayerListHeaderFooter: return 0x48;
+ case pktPlayerMaxSpeed: return 0x4b;
+ case pktPlayerMoveLook: return 0x2e;
+ case pktPluginMessage: return 0x18;
+ case pktRemoveEntityEffect: return 0x31;
+ case pktResourcePack: return 0x32;
+ case pktRespawn: return 0x33;
+ case pktScoreboardObjective: return 0x3f;
+ case pktSpawnExperienceOrb: return 0x01;
+ case pktSpawnGlobalEntity: return 0x02;
+ case pktSpawnObject: return 0x00;
+ case pktSpawnOtherPlayer: return 0x05;
+ case pktSpawnPainting: return 0x04;
+ case pktSpawnPosition: return 0x43;
+ case pktSoundEffect: return 0x19;
+ case pktSoundParticleEffect: return 0x21;
+ case pktSpawnMob: return 0x03;
+ case pktStartCompression: return 0x03;
+ case pktStatistics: return 0x07;
+ case pktStatusResponse: return 0x00;
+ case pktTabCompletionResults: return 0x0e;
+ case pktTeleportEntity: return 0x4a;
+ case pktTimeUpdate: return 0x44;
+ case pktTitle: return 0x45;
+ case pktUnloadChunk: return 0x1d;
+ case pktUpdateBlockEntity: return 0x09;
+ case pktUpdateHealth: return 0x3e;
+ case pktUpdateScore: return 0x42;
+ case pktUpdateSign: return 0x46;
+ case pktUseBed: return 0x2f;
+ case pktWeather: return 0x1e;
+ case pktWindowClose: return 0x12;
+ case pktWindowItems: return 0x14;
+ case pktWindowOpen: return 0x13;
+ case pktWindowProperty: return 0x15;
// Unsupported packets
case pktUnlockRecipe:
@@ -2309,11 +2310,12 @@ UInt32 cProtocol_1_9_4::GetPacketID(cProtocol::ePacketType a_Packet)
{
switch (a_Packet)
{
- case pktCollectEntity: return 0x48;
- case pktEntityEffect: return 0x4b;
- case pktEntityProperties: return 0x4a;
- case pktPlayerMaxSpeed: return 0x4a;
- case pktTeleportEntity: return 0x49;
+ case pktCollectEntity: return 0x48;
+ case pktEntityEffect: return 0x4b;
+ case pktEntityProperties: return 0x4a;
+ case pktPlayerMaxSpeed: return 0x4a;
+ case pktPlayerListHeaderFooter: return 0x47;
+ case pktTeleportEntity: return 0x49;
default: return Super::GetPacketID(a_Packet);
}
diff --git a/src/Root.cpp b/src/Root.cpp
index 57782fbb4..a1023e8e9 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -648,6 +648,18 @@ void cRoot::BroadcastPlayerListsRemovePlayer(const cPlayer & a_Player, const cCl
+void cRoot::BroadcastPlayerListsHeaderFooter(const cCompositeChat & a_Header, const cCompositeChat & a_Footer)
+{
+ for (auto & Entry : m_WorldsByName)
+ {
+ Entry.second.BroadcastPlayerListHeaderFooter(a_Header, a_Footer);
+ }
+}
+
+
+
+
+
void cRoot::BroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix)
{
for (auto & Entry : m_WorldsByName)
diff --git a/src/Root.h b/src/Root.h
index 696b31ce3..74a0acbb4 100644
--- a/src/Root.h
+++ b/src/Root.h
@@ -166,6 +166,9 @@ public:
/** Broadcast playerlist removal through all worlds */
void BroadcastPlayerListsRemovePlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
+ /** Broadcast playerlist header and footer through all worlds */
+ void BroadcastPlayerListsHeaderFooter(const cCompositeChat & a_Header, const cCompositeChat & a_Footer); // tolua_export
+
// tolua_begin
/** Sends a chat message to all connected clients (in all worlds) */
diff --git a/src/World.h b/src/World.h
index 2fc5040b8..9d68ff47d 100644
--- a/src/World.h
+++ b/src/World.h
@@ -209,6 +209,7 @@ public:
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle * a_Exclude = nullptr) override; // Exported in ManualBindings_World.cpp
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, const cClientHandle * a_Exclude = nullptr) override; // Exported in ManualBindings_World.cpp
virtual void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
+ virtual void BroadcastPlayerListHeaderFooter (const cCompositeChat & a_Header, const cCompositeChat & a_Footer) override; // tolua_export
virtual void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
virtual void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
virtual void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;