1
0

Initial resource pack support (#4622)

This commit is contained in:
Mat 2020-04-08 00:23:54 +03:00 committed by GitHub
parent 19ad96561c
commit 6a21bf979c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 146 additions and 4 deletions

View File

@ -2929,6 +2929,15 @@ void cClientHandle::SendExperienceOrb(const cExpOrb & a_ExpOrb)
void cClientHandle::SendResourcePack(const AString & a_ResourcePackUrl)
{
m_Protocol->SendResourcePack(a_ResourcePackUrl);
}
void cClientHandle::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
{
m_Protocol->SendScoreboardObjective(a_Name, a_DisplayName, a_Mode);

View File

@ -197,6 +197,7 @@ public: // tolua_export
void SendPlayerSpawn (const cPlayer & a_Player);
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
void SendResourcePack (const AString & a_ResourcePackUrl);
void SendResetTitle (void); // tolua_export
void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false);
void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);

View File

@ -101,6 +101,7 @@ AString cPacketizer::PacketTypeToStr(cProtocol::ePacketType a_PacketType)
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";

View File

@ -112,6 +112,7 @@ public:
pktPlayerMoveLook,
pktPluginMessage,
pktRemoveEntityEffect,
pktResourcePack,
pktRespawn,
pktScoreboardObjective,
pktSpawnObject,
@ -201,6 +202,7 @@ public:
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
virtual void SendResetTitle (void) = 0;
virtual void SendResourcePack (const AString & a_ResourcePackUrl) = 0;
virtual void SendRespawn (eDimension a_Dimension) = 0;
virtual void SendExperience (void) = 0;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;

View File

@ -700,6 +700,16 @@ void cProtocolRecognizer::SendResetTitle(void)
void cProtocolRecognizer::SendResourcePack(const AString & a_ResourcePackUrl)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendResourcePack(a_ResourcePackUrl);
}
void cProtocolRecognizer::SendRespawn(eDimension a_Dimension)
{
ASSERT(m_Protocol != nullptr);

View File

@ -104,6 +104,7 @@ public:
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendResetTitle (void) override;
virtual void SendResourcePack (const AString & a_ResourcePackUrl) override;
virtual void SendRespawn (eDimension a_Dimension) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;

View File

@ -45,6 +45,19 @@ Implements the 1.10 protocol classes:
#define HANDLE_READ(ByteBuf, Proc, Type, Var) \
Type Var; \
do { \
if (!ByteBuf.Proc(Var))\
{\
return;\
} \
} while (false)
// The disabled error is intended, since the Metadata have overlapping indexes
// based on the type of the Entity.
//
@ -318,6 +331,15 @@ void cProtocol_1_10_0::SendSoundEffect(const AString & a_SoundName, double a_X,
void cProtocol_1_10_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status);
}
void cProtocol_1_10_0::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{
cServer * Server = cRoot::Get()->GetServer();

View File

@ -29,6 +29,7 @@ public:
virtual void SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
protected:

View File

@ -986,6 +986,7 @@ UInt32 cProtocol_1_12::GetPacketID(cProtocol::ePacketType a_Packet)
case pktLeashEntity: return 0x3c;
case pktPlayerMaxSpeed: return 0x4d;
case pktRemoveEntityEffect: return 0x32;
case pktResourcePack: return 0x33;
case pktRespawn: return 0x34;
case pktScoreboardObjective: return 0x41;
case pktSpawnPosition: return 0x45;
@ -1079,7 +1080,7 @@ bool cProtocol_1_12::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTyp
case 0x15: HandlePacketEntityAction(a_ByteBuffer); return true;
case 0x16: HandlePacketSteerVehicle(a_ByteBuffer); return true;
case 0x17: HandlePacketCraftingBookData(a_ByteBuffer); return true;
case 0x18: break; // Resource pack status - not yet implemented
case 0x18: HandlePacketResourcePackStatus(a_ByteBuffer); return true;
case 0x19: HandlePacketAdvancementTab(a_ByteBuffer); return true;
case 0x1a: HandlePacketSlotSelect(a_ByteBuffer); return true;
case 0x1b: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
@ -1151,6 +1152,7 @@ UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet)
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;
@ -1268,7 +1270,7 @@ bool cProtocol_1_12_1::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketT
case 0x15: HandlePacketEntityAction(a_ByteBuffer); return true;
case 0x16: HandlePacketSteerVehicle(a_ByteBuffer); return true;
case 0x17: HandlePacketCraftingBookData(a_ByteBuffer); return true;
case 0x18: break; // Resource pack status - not yet implemented
case 0x18: HandlePacketResourcePackStatus(a_ByteBuffer); return true;
case 0x19: HandlePacketAdvancementTab(a_ByteBuffer); return true;
case 0x1a: HandlePacketSlotSelect(a_ByteBuffer); return true;
case 0x1b: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;

View File

@ -1147,6 +1147,25 @@ void cProtocol_1_8_0::SendResetTitle(void)
void cProtocol_1_8_0::SendResourcePack(const AString & a_ResourcePackUrl)
{
cPacketizer Pkt(*this, pktResourcePack);
cSha1Checksum Checksum;
Checksum.Update(reinterpret_cast<const Byte *>(a_ResourcePackUrl.c_str()), a_ResourcePackUrl.size());
Byte Digest[20];
Checksum.Finalize(Digest);
AString Sha1Output;
cSha1Checksum::DigestToHex(Digest, Sha1Output);
Pkt.WriteString(a_ResourcePackUrl);
Pkt.WriteString(Sha1Output);
}
void cProtocol_1_8_0::SendRespawn(eDimension a_Dimension)
{
@ -2152,6 +2171,7 @@ UInt32 cProtocol_1_8_0::GetPacketID(ePacketType a_PacketType)
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;
@ -2250,6 +2270,7 @@ bool cProtocol_1_8_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTy
case 0x16: HandlePacketClientStatus (a_ByteBuffer); return true;
case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return true;
case 0x18: HandlePacketSpectate (a_ByteBuffer); return true;
case 0x19: HandlePacketResourcePackStatus (a_ByteBuffer); return true;
}
break;
}
@ -2708,6 +2729,16 @@ void cProtocol_1_8_0::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Hash);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status);
}
void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum);

View File

@ -91,6 +91,7 @@ public:
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendResetTitle (void) override;
virtual void SendResourcePack (const AString & a_ResourcePackUrl) override;
virtual void SendRespawn (eDimension a_Dimension) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendExperience (void) override;
@ -197,6 +198,7 @@ protected:
void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketResourcePackStatus (cByteBuffer & a_ByteBuffer);
void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer);
void HandlePacketSpectate (cByteBuffer & a_ByteBuffer);
void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);

View File

@ -1233,6 +1233,25 @@ void cProtocol_1_9_0::SendResetTitle(void)
void cProtocol_1_9_0::SendResourcePack(const AString & a_ResourcePackUrl)
{
cPacketizer Pkt(*this, pktResourcePack);
cSha1Checksum Checksum;
Checksum.Update(reinterpret_cast<const Byte *>(a_ResourcePackUrl.c_str()), a_ResourcePackUrl.size());
Byte Digest[20];
Checksum.Finalize(Digest);
AString Sha1Output;
cSha1Checksum::DigestToHex(Digest, Sha1Output);
Pkt.WriteString(a_ResourcePackUrl);
Pkt.WriteString(Sha1Output);
}
void cProtocol_1_9_0::SendRespawn(eDimension a_Dimension)
{
cPacketizer Pkt(*this, pktRespawn);
@ -2209,6 +2228,7 @@ UInt32 cProtocol_1_9_0::GetPacketID(cProtocol::ePacketType a_Packet)
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;
@ -2299,7 +2319,7 @@ bool cProtocol_1_9_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTy
case 0x13: HandlePacketBlockDig (a_ByteBuffer); return true;
case 0x14: HandlePacketEntityAction (a_ByteBuffer); return true;
case 0x15: HandlePacketSteerVehicle (a_ByteBuffer); return true;
case 0x16: break; // Resource pack status - not yet implemented
case 0x16: HandlePacketResourcePackStatus (a_ByteBuffer); return true;
case 0x17: HandlePacketSlotSelect (a_ByteBuffer); return true;
case 0x18: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
case 0x19: HandlePacketUpdateSign (a_ByteBuffer); return true;
@ -2804,6 +2824,16 @@ void cProtocol_1_9_0::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
void cProtocol_1_9_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Hash);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status);
}
void cProtocol_1_9_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum);

View File

@ -99,6 +99,7 @@ public:
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendResetTitle (void) override;
virtual void SendResourcePack (const AString & a_ResourcePackUrl) override;
virtual void SendRespawn (eDimension a_Dimension) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
@ -208,6 +209,7 @@ protected:
virtual void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketResourcePackStatus (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketSpectate (cByteBuffer & a_ByteBuffer);

View File

@ -170,6 +170,7 @@ bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_Shoul
m_MaxPlayers = static_cast<size_t>(a_Settings.GetValueSetI("Server", "MaxPlayers", 100));
m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false);
m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false);
m_ResourcePackUrl = a_Settings.GetValueSet("Server", "ResourcePackUrl", "");
m_FaviconData = Base64Encode(cFile::ReadWholeFile(FILE_IO_PREFIX + AString("favicon.png"))); // Will return empty string if file nonexistant; client doesn't mind

View File

@ -94,6 +94,8 @@ public:
// tolua_end
const AString & GetResourcePackUrl(void) { return m_ResourcePackUrl; }
bool Start(void);
bool Command(cClientHandle & a_Client, AString & a_Cmd);
@ -214,6 +216,7 @@ private:
AString m_FaviconData;
size_t m_MaxPlayers;
bool m_bIsHardcore;
AString m_ResourcePackUrl;
/** Map of protocol version to Forge mods (map of ModName -> ModVersionString) */
std::map<UInt32, AStringMap> m_ForgeModsByVersion;

View File

@ -3561,6 +3561,13 @@ void cWorld::AddQueuedPlayers(void)
Client->SendPlayerMoveLook();
Client->SendHealth();
Client->SendWholeInventory(*Player->GetWindow());
// Send resource pack
auto ResourcePackUrl = cRoot::Get()->GetServer()->GetResourcePackUrl();
if (!ResourcePackUrl.empty())
{
Client->SendResourcePack(ResourcePackUrl);
}
}
} // for itr - PlayersToAdd[]

View File

@ -85,6 +85,20 @@ void cSha1Checksum::Finalize(cSha1Checksum::Checksum & a_Output)
void cSha1Checksum::DigestToHex(const Checksum & a_Digest, AString & a_Out)
{
a_Out.clear();
a_Out.reserve(40);
for (int i = 0; i < 20; i++)
{
AppendPrintf(a_Out, "%x", a_Digest[i]);
}
}
void cSha1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out)
{
Checksum Digest;

View File

@ -32,10 +32,13 @@ public:
/** Returns true if the object is accepts more input data, false if Finalize()-d (need to Restart()) */
bool DoesAcceptInput(void) const { return m_DoesAcceptInput; }
/** Converts a SHA1 digest into hex */
static void DigestToHex(const Checksum & a_Digest, AString & a_Out);
/** Converts a raw 160-bit SHA1 digest into a Java Hex representation
According to http://wiki.vg/Protocol_Encryption
*/
static void DigestToJava(const Checksum & a_Digest, AString & a_JavaOut);
static void DigestToJava(const Checksum & a_Digest, AString & a_Out);
/** Clears the current context and start a new checksum calculation */
void Restart(void);