Added temporary block type mapping for 1.13+ protocols.
This commit is contained in:
parent
e234fbdafe
commit
4aef80b47e
@ -1,6 +1,7 @@
|
|||||||
Cuberite
|
Cuberite
|
||||||
Plugins
|
Plugins
|
||||||
Prefabs
|
Prefabs
|
||||||
|
Protocol
|
||||||
webadmin
|
webadmin
|
||||||
BACKERS
|
BACKERS
|
||||||
brewing.txt
|
brewing.txt
|
||||||
|
@ -2,6 +2,7 @@ Cuberite.exe
|
|||||||
*.dll
|
*.dll
|
||||||
Plugins
|
Plugins
|
||||||
Prefabs
|
Prefabs
|
||||||
|
Protocol
|
||||||
webadmin
|
webadmin
|
||||||
BACKERS
|
BACKERS
|
||||||
brewing.txt
|
brewing.txt
|
||||||
|
@ -10,7 +10,7 @@ CommonPrefix minecraft:
|
|||||||
1 4 polished_diorite
|
1 4 polished_diorite
|
||||||
1 5 andesite
|
1 5 andesite
|
||||||
1 6 polished_andesite
|
1 6 polished_andesite
|
||||||
2 0 grass_block
|
2 0 grass_block snowy false
|
||||||
3 0 dirt
|
3 0 dirt
|
||||||
3 1 coarse_dirt
|
3 1 coarse_dirt
|
||||||
3 2 podzol
|
3 2 podzol
|
||||||
@ -38,14 +38,26 @@ CommonPrefix minecraft:
|
|||||||
14 0 gold_ore
|
14 0 gold_ore
|
||||||
15 0 iron_ore
|
15 0 iron_ore
|
||||||
16 0 coal_ore
|
16 0 coal_ore
|
||||||
17 0 oak_log
|
17 0 oak_log axis y
|
||||||
17 1 spruce_log
|
17 1 spruce_log axis y
|
||||||
17 2 birch_log
|
17 2 birch_log axis y
|
||||||
17 3 jungle_log
|
17 3 jungle_log axis y
|
||||||
18 0 oak_leaves
|
17 4 oak_log axis x
|
||||||
18 1 spruce_leaves
|
17 5 spruce_log axis x
|
||||||
18 2 birch_leaves
|
17 6 birch_log axis x
|
||||||
18 3 jungle_leaves
|
17 7 jungle_log axis x
|
||||||
|
17 8 oak_log axis z
|
||||||
|
17 9 spruce_log axis z
|
||||||
|
17 10 birch_log axis z
|
||||||
|
17 11 jungle_log axis z
|
||||||
|
17 12 oak_wood axis y
|
||||||
|
17 13 spruce_wood axis y
|
||||||
|
17 14 birch_wood axis y
|
||||||
|
17 15 jungle_wood axis y
|
||||||
|
18 0 oak_leaves persistent false distance 7
|
||||||
|
18 1 spruce_leaves persistent false distance 7
|
||||||
|
18 2 birch_leaves persistent false distance 7
|
||||||
|
18 3 jungle_leaves persistent false distance 7
|
||||||
19 0 sponge
|
19 0 sponge
|
||||||
19 1 wet_sponge
|
19 1 wet_sponge
|
||||||
20 0 glass
|
20 0 glass
|
||||||
|
@ -12,6 +12,7 @@ SET (SRCS
|
|||||||
Protocol_1_11.cpp
|
Protocol_1_11.cpp
|
||||||
Protocol_1_12.cpp
|
Protocol_1_12.cpp
|
||||||
Protocol_1_13.cpp
|
Protocol_1_13.cpp
|
||||||
|
ProtocolPalettes.cpp
|
||||||
ProtocolRecognizer.cpp
|
ProtocolRecognizer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ SET (HDRS
|
|||||||
Protocol_1_11.h
|
Protocol_1_11.h
|
||||||
Protocol_1_12.h
|
Protocol_1_12.h
|
||||||
Protocol_1_13.h
|
Protocol_1_13.h
|
||||||
|
ProtocolPalettes.h
|
||||||
ProtocolRecognizer.h
|
ProtocolRecognizer.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
|
|
||||||
// ChunkDataSerializer.cpp
|
|
||||||
|
|
||||||
// Implements the cChunkDataSerializer class representing the object that can:
|
|
||||||
// - serialize chunk data to different protocol versions
|
|
||||||
// - cache such serialized data for multiple clients
|
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "ChunkDataSerializer.h"
|
#include "ChunkDataSerializer.h"
|
||||||
#include "zlib/zlib.h"
|
#include "zlib/zlib.h"
|
||||||
@ -52,7 +45,7 @@ cChunkDataSerializer::cChunkDataSerializer(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int a_ChunkZ)
|
const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int a_ChunkZ, const std::map<UInt32, UInt32> & a_BlockTypeMap)
|
||||||
{
|
{
|
||||||
Serializations::const_iterator itr = m_Serializations.find(a_Version);
|
Serializations::const_iterator itr = m_Serializations.find(a_Version);
|
||||||
if (itr != m_Serializations.end())
|
if (itr != m_Serializations.end())
|
||||||
@ -63,11 +56,10 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int
|
|||||||
AString data;
|
AString data;
|
||||||
switch (a_Version)
|
switch (a_Version)
|
||||||
{
|
{
|
||||||
case RELEASE_1_8_0: Serialize47(data, a_ChunkX, a_ChunkZ); break;
|
case RELEASE_1_8_0: Serialize47 (data, a_ChunkX, a_ChunkZ); break;
|
||||||
case RELEASE_1_9_0: Serialize107(data, a_ChunkX, a_ChunkZ); break;
|
case RELEASE_1_9_0: Serialize107(data, a_ChunkX, a_ChunkZ); break;
|
||||||
case RELEASE_1_9_4: Serialize110(data, a_ChunkX, a_ChunkZ); break;
|
case RELEASE_1_9_4: Serialize110(data, a_ChunkX, a_ChunkZ); break;
|
||||||
case RELEASE_1_13: Serialize393(data, a_ChunkX, a_ChunkZ); break;
|
case RELEASE_1_13: Serialize393(data, a_ChunkX, a_ChunkZ, a_BlockTypeMap); break;
|
||||||
// TODO: Other protocol versions may serialize the data differently; implement here
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -442,10 +434,12 @@ void cChunkDataSerializer::Serialize110(AString & a_Data, int a_ChunkX, int a_Ch
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkDataSerializer::Serialize393(AString & a_Data, int a_ChunkX, int a_ChunkZ)
|
void cChunkDataSerializer::Serialize393(AString & a_Data, int a_ChunkX, int a_ChunkZ, const std::map<UInt32, UInt32> & a_BlockTypeMap)
|
||||||
{
|
{
|
||||||
// This function returns the fully compressed packet (including packet size), not the raw packet!
|
// This function returns the fully compressed packet (including packet size), not the raw packet!
|
||||||
|
|
||||||
|
ASSERT(!a_BlockTypeMap.empty()); // We need a protocol-specific translation map
|
||||||
|
|
||||||
// Create the packet:
|
// Create the packet:
|
||||||
cByteBuffer Packet(512 KiB);
|
cByteBuffer Packet(512 KiB);
|
||||||
Packet.WriteVarInt32(0x22); // Packet id (Chunk Data packet)
|
Packet.WriteVarInt32(0x22); // Packet id (Chunk Data packet)
|
||||||
@ -489,17 +483,10 @@ void cChunkDataSerializer::Serialize393(AString & a_Data, int a_ChunkX, int a_Ch
|
|||||||
|
|
||||||
for (size_t Index = 0; Index < cChunkData::SectionBlockCount; Index++)
|
for (size_t Index = 0; Index < cChunkData::SectionBlockCount; Index++)
|
||||||
{
|
{
|
||||||
UInt64 Value = a_Section.m_BlockTypes[Index];
|
UInt32 blockType = a_Section.m_BlockTypes[Index];
|
||||||
/*
|
UInt32 blockMeta = (a_Section.m_BlockMetas[Index / 2] >> ((Index % 2) * 4)) & 0x0f;
|
||||||
if (Index % 2 == 0)
|
auto itr = a_BlockTypeMap.find(blockType * 16 | blockMeta);
|
||||||
{
|
UInt64 Value = (itr == a_BlockTypeMap.end()) ? 0 :itr->second;
|
||||||
Value |= a_Section.m_BlockMetas[Index / 2] & 0x0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Value |= a_Section.m_BlockMetas[Index / 2] >> 4;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Value &= Mask; // It shouldn't go out of bounds, but it's still worth being careful
|
Value &= Mask; // It shouldn't go out of bounds, but it's still worth being careful
|
||||||
|
|
||||||
// Painful part where we write data into the long array. Based off of the normal code.
|
// Painful part where we write data into the long array. Based off of the normal code.
|
||||||
|
@ -1,31 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
// ChunkDataSerializer.h
|
|
||||||
|
|
||||||
// Interfaces to the cChunkDataSerializer class representing the object that can:
|
|
||||||
// - serialize chunk data to different protocol versions
|
|
||||||
// - cache such serialized data for multiple clients
|
|
||||||
|
|
||||||
#include "../ChunkData.h"
|
#include "../ChunkData.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Serializes one chunk's data to (possibly multiple) protocol versions.
|
||||||
|
Caches the serialized data for as long as this object lives, so that the same data can be sent to
|
||||||
|
other clients using the same protocol. */
|
||||||
class cChunkDataSerializer
|
class cChunkDataSerializer
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
const cChunkData & m_Data;
|
|
||||||
const unsigned char * m_BiomeData;
|
|
||||||
const eDimension m_Dimension;
|
|
||||||
|
|
||||||
typedef std::map<int, AString> Serializations;
|
|
||||||
|
|
||||||
Serializations m_Serializations;
|
|
||||||
|
|
||||||
void Serialize47 (AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8
|
|
||||||
void Serialize107(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.9
|
|
||||||
void Serialize110(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.9.4
|
|
||||||
void Serialize393(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.13
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -41,7 +26,34 @@ public:
|
|||||||
const eDimension a_Dimension
|
const eDimension a_Dimension
|
||||||
);
|
);
|
||||||
|
|
||||||
const AString & Serialize(int a_Version, int a_ChunkX, int a_ChunkZ); // Returns one of the internal m_Serializations[]
|
/** Serializes the contained chunk data into the specified protocol version.
|
||||||
|
TEMPORARY: a_BlockTypeMap is used for the 1.13+ protocols to map from BLOCKTYPE#META to NetBlockID.
|
||||||
|
a_BlockTypeMap is ignored for pre-1.13 protocols. */
|
||||||
|
const AString & Serialize(int a_Version, int a_ChunkX, int a_ChunkZ, const std::map<UInt32, UInt32> & a_BlockTypeMap);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
using Serializations = std::map<int, AString>;
|
||||||
|
|
||||||
|
|
||||||
|
/** The data read from the chunk, to be serialized. */
|
||||||
|
const cChunkData & m_Data;
|
||||||
|
|
||||||
|
/** The biomes in the chunk, to be serialized. */
|
||||||
|
const unsigned char * m_BiomeData;
|
||||||
|
|
||||||
|
/** The dimension where the chunk resides. */
|
||||||
|
const eDimension m_Dimension;
|
||||||
|
|
||||||
|
/** The per-protocol serialized data, cached for reuse for other clients. */
|
||||||
|
Serializations m_Serializations;
|
||||||
|
|
||||||
|
|
||||||
|
void Serialize47 (AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8
|
||||||
|
void Serialize107(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.9
|
||||||
|
void Serialize110(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.9.4
|
||||||
|
void Serialize393(AString & a_Data, int a_ChunkX, int a_ChunkZ, const std::map<UInt32, UInt32> & a_BlockTypeMap); // Release 1.13
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ public:
|
|||||||
virtual ~cProtocol() {}
|
virtual ~cProtocol() {}
|
||||||
|
|
||||||
|
|
||||||
|
/** Called after construction so that the protocol class can initialize itself.
|
||||||
|
Throws a std::exception descendant on failure; the client is kicked
|
||||||
|
with the exception's message as a result. */
|
||||||
|
virtual void Initialize(cClientHandle & a_Client) {}
|
||||||
|
|
||||||
/** Logical types of outgoing packets.
|
/** Logical types of outgoing packets.
|
||||||
These values get translated to on-wire packet IDs in GetPacketID(), specific for each protocol.
|
These values get translated to on-wire packet IDs in GetPacketID(), specific for each protocol.
|
||||||
This is mainly useful for protocol sub-versions that re-number the packets while using mostly the same packet layout. */
|
This is mainly useful for protocol sub-versions that re-number the packets while using mostly the same packet layout. */
|
||||||
|
107
src/Protocol/ProtocolPalettes.cpp
Normal file
107
src/Protocol/ProtocolPalettes.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include "Globals.h"
|
||||||
|
#include "ProtocolPalettes.h"
|
||||||
|
#include "../BlockTypePalette.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ProtocolPalettes::load(const AString & aProtocolFolder)
|
||||||
|
{
|
||||||
|
auto contents = cFile::GetFolderContents(aProtocolFolder);
|
||||||
|
for (const auto & c: contents)
|
||||||
|
{
|
||||||
|
auto fullName = aProtocolFolder + cFile::PathSeparator() + c;
|
||||||
|
if (cFile::IsFolder(fullName))
|
||||||
|
{
|
||||||
|
loadSingleVersion(c, fullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<const BlockTypePalette> ProtocolPalettes::blockTypePalette(const AString & aProtocolVersion) const
|
||||||
|
{
|
||||||
|
cCSLock lock(mCS);
|
||||||
|
auto itr = mPalettes.find(aProtocolVersion);
|
||||||
|
if (itr == mPalettes.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return itr->second.mBlockTypePalette;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<AString> ProtocolPalettes::protocolVersions() const
|
||||||
|
{
|
||||||
|
cCSLock lock(mCS);
|
||||||
|
|
||||||
|
std::vector<AString> res;
|
||||||
|
for (const auto & p: mPalettes)
|
||||||
|
{
|
||||||
|
res.push_back(p.first);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ProtocolPalettes::loadSingleVersion(const AString & aProtocolVersion, const AString & aFolder)
|
||||||
|
{
|
||||||
|
// Get the file list, sort by name
|
||||||
|
auto contents = cFile::GetFolderContents(aFolder);
|
||||||
|
std::sort(contents.begin(), contents.end());
|
||||||
|
|
||||||
|
// Load files into the palettes:
|
||||||
|
cCSLock lock(mCS);
|
||||||
|
auto & pal = mPalettes[aProtocolVersion];
|
||||||
|
for (const auto & c: contents)
|
||||||
|
{
|
||||||
|
if (c.length() < 8)
|
||||||
|
{
|
||||||
|
// Name too short, can't have the ".btp.txt" etc. suffix
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto fnam = aFolder + cFile::PathSeparator() + c;
|
||||||
|
if (!cFile::IsFile(fnam))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto fileType = c.substr(c.length() - 8);
|
||||||
|
if ((fileType == ".btp.txt") || (c == "blocks.json"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pal.mBlockTypePalette->loadFromString(cFile::ReadWholeFile(fnam));
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// Ignore silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((fileType == ".itp.txt") || (c == "items.json"))
|
||||||
|
{
|
||||||
|
// TODO: Load item type palette
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ProtocolPalettes::Palettes:
|
||||||
|
|
||||||
|
ProtocolPalettes::Palettes::Palettes():
|
||||||
|
mBlockTypePalette(new BlockTypePalette)
|
||||||
|
{
|
||||||
|
}
|
63
src/Protocol/ProtocolPalettes.h
Normal file
63
src/Protocol/ProtocolPalettes.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../OSSupport/CriticalSection.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fwd:
|
||||||
|
class BlockTypePalette;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Loads the protocol-specific palettes on startup and provides them to the individual protocol
|
||||||
|
instances when they are created.
|
||||||
|
Uses the data in the $/Server/Protocol folder. Each protocol version has a subfolder there,
|
||||||
|
containing possibly multiple palette files. All the files are loaded in sequence (alpha-sorted),
|
||||||
|
into the palette corresponding to the file's extension (*.btp.txt -> BlockTypePalette).
|
||||||
|
Provides thread safety for the data properly. */
|
||||||
|
class ProtocolPalettes
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Loads all the per-protocol palettes.
|
||||||
|
aProtocolFolder is the folder that contains a subfolder for each protocol version;
|
||||||
|
each subfolder contains the protocol-specific palettes (as in $/Server/Protocol)
|
||||||
|
If a protocol version is already loaded, yet present in the folder, the newly loaded data is merged
|
||||||
|
into the current data.
|
||||||
|
Always succeeds (even when there are no palettes). */
|
||||||
|
void load(const AString & aProtocolFolder);
|
||||||
|
|
||||||
|
/** Returns the BlockTypePalette for the specified protocol.
|
||||||
|
Returns nullptr if no such palette has been loaded. */
|
||||||
|
std::shared_ptr<const BlockTypePalette> blockTypePalette(const AString & aProtocolVersion) const;
|
||||||
|
|
||||||
|
/** Returns the version names of all protocols that have been loaded. */
|
||||||
|
std::vector<AString> protocolVersions() const;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** Container for all palettes for a single protocol. */
|
||||||
|
struct Palettes
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlockTypePalette> mBlockTypePalette;
|
||||||
|
// TODO: ItemTypePalette
|
||||||
|
|
||||||
|
Palettes();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** The CS protecting all members against multithreaded access. */
|
||||||
|
mutable cCriticalSection mCS;
|
||||||
|
|
||||||
|
/** The map of protocol version -> all its palettes. */
|
||||||
|
std::map<AString, Palettes> mPalettes;
|
||||||
|
|
||||||
|
|
||||||
|
/** Loads all the palettes from the specified folder into mPalettes under the aProtocolVersion key. */
|
||||||
|
void loadSingleVersion(const AString & aProtocolVersion, const AString & aFolder);
|
||||||
|
};
|
@ -1038,7 +1038,24 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void)
|
|||||||
// Not enough bytes for the packet, keep waiting
|
// Not enough bytes for the packet, keep waiting
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar);
|
if (!TryRecognizeLengthedProtocol(PacketLen - ReadSoFar))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The protocol has been recognized, initialize it:
|
||||||
|
ASSERT(m_Protocol != nullptr);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_Protocol->Initialize(*m_Client);
|
||||||
|
}
|
||||||
|
catch (const std::exception & exc)
|
||||||
|
{
|
||||||
|
m_Client->Kick(exc.what());
|
||||||
|
m_Protocol.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ Implements the 1.13 protocol classes:
|
|||||||
#include "ProtocolRecognizer.h"
|
#include "ProtocolRecognizer.h"
|
||||||
#include "ChunkDataSerializer.h"
|
#include "ChunkDataSerializer.h"
|
||||||
#include "Packetizer.h"
|
#include "Packetizer.h"
|
||||||
|
#include "ProtocolPalettes.h"
|
||||||
|
|
||||||
#include "../Entities/Boat.h"
|
#include "../Entities/Boat.h"
|
||||||
#include "../Entities/Minecart.h"
|
#include "../Entities/Minecart.h"
|
||||||
@ -21,9 +22,11 @@ Implements the 1.13 protocol classes:
|
|||||||
#include "../Entities/FireworkEntity.h"
|
#include "../Entities/FireworkEntity.h"
|
||||||
#include "../Entities/SplashPotionEntity.h"
|
#include "../Entities/SplashPotionEntity.h"
|
||||||
|
|
||||||
|
#include "../BlockTypePalette.h"
|
||||||
|
#include "../ClientHandle.h"
|
||||||
#include "../Root.h"
|
#include "../Root.h"
|
||||||
#include "../Server.h"
|
#include "../Server.h"
|
||||||
#include "../ClientHandle.h"
|
|
||||||
#include "../Bindings/PluginManager.h"
|
#include "../Bindings/PluginManager.h"
|
||||||
|
|
||||||
|
|
||||||
@ -69,6 +72,25 @@ cProtocol_1_13::cProtocol_1_13(cClientHandle * a_Client, const AString & a_Serve
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol_1_13::Initialize(cClientHandle & a_Client)
|
||||||
|
{
|
||||||
|
// Get the palettes; fail if not available:
|
||||||
|
auto paletteVersion = this->GetPaletteVersion();
|
||||||
|
m_BlockTypePalette = cRoot::Get()->GetProtocolPalettes().blockTypePalette(paletteVersion);
|
||||||
|
if (m_BlockTypePalette == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(Printf("This server doesn't support protocol %s.", paletteVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the palette into the temporary BLOCKTYPE -> NetBlockID map:
|
||||||
|
auto upg = cRoot::Get()->GetUpgradeBlockTypePalette();
|
||||||
|
m_BlockTypeMap = m_BlockTypePalette->createTransformMapWithFallback(upg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
|
UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
|
||||||
{
|
{
|
||||||
switch (a_PacketType)
|
switch (a_PacketType)
|
||||||
@ -132,6 +154,15 @@ UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AString cProtocol_1_13::GetPaletteVersion() const
|
||||||
|
{
|
||||||
|
return "1.13";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
|
bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
|
||||||
{
|
{
|
||||||
if (m_State != 3)
|
if (m_State != 3)
|
||||||
@ -292,7 +323,7 @@ void cProtocol_1_13::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali
|
|||||||
{
|
{
|
||||||
ASSERT(m_State == 3); // In game mode?
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_13, a_ChunkX, a_ChunkZ);
|
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_13, a_ChunkX, a_ChunkZ, m_BlockTypeMap);
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
SendData(ChunkData.data(), ChunkData.size());
|
SendData(ChunkData.data(), ChunkData.size());
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,13 @@ Declares the 1.13 protocol classes:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fwd:
|
||||||
|
class BlockTypePalette;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cProtocol_1_13 :
|
class cProtocol_1_13 :
|
||||||
public cProtocol_1_12_2
|
public cProtocol_1_12_2
|
||||||
{
|
{
|
||||||
@ -28,8 +35,24 @@ class cProtocol_1_13 :
|
|||||||
public:
|
public:
|
||||||
cProtocol_1_13(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
cProtocol_1_13(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
||||||
|
|
||||||
|
virtual void Initialize(cClientHandle & a_Client) override;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/** The palette used to transform internal block type palette into the protocol-specific ID. */
|
||||||
|
std::shared_ptr<const BlockTypePalette> m_BlockTypePalette;
|
||||||
|
|
||||||
|
/** Temporary hack for initial 1.13+ support while keeping BLOCKTYPE data:
|
||||||
|
Map of the BLOCKTYPE#META to the protocol-specific NetBlockID. */
|
||||||
|
std::map<UInt32, UInt32> m_BlockTypeMap;
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the string identifying the palettes' version, such as "1.13" or "1.14.4".
|
||||||
|
The palettes for that version are loaded into m_BlockTypePalette and m_ItemTypePalette. */
|
||||||
|
virtual AString GetPaletteVersion() const;
|
||||||
|
|
||||||
|
// Outgoing packet type translation:
|
||||||
virtual UInt32 GetPacketID(ePacketType a_PacketType) override;
|
virtual UInt32 GetPacketID(ePacketType a_PacketType) override;
|
||||||
|
|
||||||
// Packet receiving:
|
// Packet receiving:
|
||||||
|
@ -307,7 +307,7 @@ void cProtocol_1_8_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerial
|
|||||||
|
|
||||||
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
||||||
// This contains the flags and bitmasks, too
|
// This contains the flags and bitmasks, too
|
||||||
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ);
|
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ, {});
|
||||||
|
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
SendData(ChunkData.data(), ChunkData.size());
|
SendData(ChunkData.data(), ChunkData.size());
|
||||||
|
@ -351,7 +351,7 @@ void cProtocol_1_9_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerial
|
|||||||
|
|
||||||
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
||||||
// This contains the flags and bitmasks, too
|
// This contains the flags and bitmasks, too
|
||||||
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_9_0, a_ChunkX, a_ChunkZ);
|
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_9_0, a_ChunkX, a_ChunkZ, {});
|
||||||
|
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
SendData(ChunkData.data(), ChunkData.size());
|
SendData(ChunkData.data(), ChunkData.size());
|
||||||
@ -4513,7 +4513,7 @@ void cProtocol_1_9_4::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerial
|
|||||||
|
|
||||||
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
||||||
// This contains the flags and bitmasks, too
|
// This contains the flags and bitmasks, too
|
||||||
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_9_4, a_ChunkX, a_ChunkZ);
|
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_9_4, a_ChunkX, a_ChunkZ, {});
|
||||||
|
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
SendData(ChunkData.data(), ChunkData.size());
|
SendData(ChunkData.data(), ChunkData.size());
|
||||||
|
61
src/Root.cpp
61
src/Root.cpp
@ -40,6 +40,7 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "ClientHandle.h"
|
#include "ClientHandle.h"
|
||||||
#include "BlockTypePalette.h"
|
#include "BlockTypePalette.h"
|
||||||
|
#include "Protocol/ProtocolPalettes.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -193,23 +194,7 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
|
|||||||
// cClientHandle::FASTBREAK_PERCENTAGE = settingsRepo->GetValueSetI("AntiCheat", "FastBreakPercentage", 97) / 100.0f;
|
// cClientHandle::FASTBREAK_PERCENTAGE = settingsRepo->GetValueSetI("AntiCheat", "FastBreakPercentage", 97) / 100.0f;
|
||||||
cClientHandle::FASTBREAK_PERCENTAGE = 0; // AntiCheat disabled due to bugs. We will enabled it once they are fixed. See #3506.
|
cClientHandle::FASTBREAK_PERCENTAGE = 0; // AntiCheat disabled due to bugs. We will enabled it once they are fixed. See #3506.
|
||||||
|
|
||||||
// Load the UpgradeBlockTypePalette:
|
LoadPalettes(settingsRepo->GetValueSet("Folders", "ProtocolPalettes", "Protocol"));
|
||||||
LOG("Loading UpgradeBlockTypePalette...");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto paletteStr = cFile::ReadWholeFile("Protocol/UpgradeBlockTypePalette.txt");
|
|
||||||
if (paletteStr.empty())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("File is empty");
|
|
||||||
}
|
|
||||||
m_UpgradeBlockTypePalette.reset(new BlockTypePalette);
|
|
||||||
m_UpgradeBlockTypePalette->loadFromString(paletteStr);
|
|
||||||
}
|
|
||||||
catch (const std::exception & exc)
|
|
||||||
{
|
|
||||||
LOGERROR("Failed to load the Upgrade block type palette from Protocol/UpgradeBlockTypePalette.txt: %s\nAborting", exc.what());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_MojangAPI = new cMojangAPI;
|
m_MojangAPI = new cMojangAPI;
|
||||||
bool ShouldAuthenticate = settingsRepo->GetValueSetB("Authentication", "Authenticate", true);
|
bool ShouldAuthenticate = settingsRepo->GetValueSetB("Authentication", "Authenticate", true);
|
||||||
@ -416,6 +401,48 @@ void cRoot::LoadGlobalSettings()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cRoot::LoadPalettes(const AString & aProtocolFolder)
|
||||||
|
{
|
||||||
|
LOG("Loading UpgradeBlockTypePalette...");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto paletteStr = cFile::ReadWholeFile(aProtocolFolder + cFile::PathSeparator() + "UpgradeBlockTypePalette.txt");
|
||||||
|
if (paletteStr.empty())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("File is empty");
|
||||||
|
}
|
||||||
|
m_UpgradeBlockTypePalette.reset(new BlockTypePalette);
|
||||||
|
m_UpgradeBlockTypePalette->loadFromString(paletteStr);
|
||||||
|
}
|
||||||
|
catch (const std::exception & exc)
|
||||||
|
{
|
||||||
|
LOGERROR("Failed to load the Upgrade block type palette from %s/UpgradeBlockTypePalette.txt: %s\nAborting",
|
||||||
|
aProtocolFolder, exc.what()
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: This can take a lot of time in MSVC debug builds
|
||||||
|
// If impatient, edit the settings.ini: [Folders] ProtocolPalettes=DummyDir; copy only one palette to DummyDir
|
||||||
|
LOG("Loading per-protocol palettes...");
|
||||||
|
m_ProtocolPalettes.reset(new ProtocolPalettes);
|
||||||
|
m_ProtocolPalettes->load(aProtocolFolder);
|
||||||
|
auto versions = m_ProtocolPalettes->protocolVersions();
|
||||||
|
if (versions.empty())
|
||||||
|
{
|
||||||
|
LOGWARNING("No per-protocol palettes were loaded");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::sort(versions.begin(), versions.end());
|
||||||
|
LOG("Loaded palettes for protocol versions: %s", StringJoin(versions, ", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cRoot::LoadWorlds(cDeadlockDetect & a_dd, cSettingsRepositoryInterface & a_Settings, bool a_IsNewIniFile)
|
void cRoot::LoadWorlds(cDeadlockDetect & a_dd, cSettingsRepositoryInterface & a_Settings, bool a_IsNewIniFile)
|
||||||
{
|
{
|
||||||
if (a_IsNewIniFile)
|
if (a_IsNewIniFile)
|
||||||
|
11
src/Root.h
11
src/Root.h
@ -29,6 +29,7 @@ class cSettingsRepositoryInterface;
|
|||||||
class cDeadlockDetect;
|
class cDeadlockDetect;
|
||||||
class cUUID;
|
class cUUID;
|
||||||
class BlockTypePalette;
|
class BlockTypePalette;
|
||||||
|
class ProtocolPalettes;
|
||||||
|
|
||||||
using cPlayerListCallback = cFunctionRef<bool(cPlayer &)>;
|
using cPlayerListCallback = cFunctionRef<bool(cPlayer &)>;
|
||||||
using cWorldListCallback = cFunctionRef<bool(cWorld &)>;
|
using cWorldListCallback = cFunctionRef<bool(cWorld &)>;
|
||||||
@ -96,6 +97,9 @@ public:
|
|||||||
/** Returns the block type palette used for upgrading blocks from pre-1.13 data. */
|
/** Returns the block type palette used for upgrading blocks from pre-1.13 data. */
|
||||||
const BlockTypePalette & GetUpgradeBlockTypePalette() const { return *m_UpgradeBlockTypePalette; }
|
const BlockTypePalette & GetUpgradeBlockTypePalette() const { return *m_UpgradeBlockTypePalette; }
|
||||||
|
|
||||||
|
/** Returns the per-protocol palettes manager. */
|
||||||
|
ProtocolPalettes & GetProtocolPalettes() const { return *m_ProtocolPalettes; }
|
||||||
|
|
||||||
/** Returns the number of ticks for how long the item would fuel a furnace. Returns zero if not a fuel */
|
/** Returns the number of ticks for how long the item would fuel a furnace. Returns zero if not a fuel */
|
||||||
static int GetFurnaceFuelBurnTime(const cItem & a_Fuel); // tolua_export
|
static int GetFurnaceFuelBurnTime(const cItem & a_Fuel); // tolua_export
|
||||||
|
|
||||||
@ -241,9 +245,16 @@ private:
|
|||||||
/** The upgrade palette for pre-1.13 blocks. */
|
/** The upgrade palette for pre-1.13 blocks. */
|
||||||
std::unique_ptr<BlockTypePalette> m_UpgradeBlockTypePalette;
|
std::unique_ptr<BlockTypePalette> m_UpgradeBlockTypePalette;
|
||||||
|
|
||||||
|
/** The per-protocol palettes manager. */
|
||||||
|
std::unique_ptr<ProtocolPalettes> m_ProtocolPalettes;
|
||||||
|
|
||||||
|
|
||||||
void LoadGlobalSettings();
|
void LoadGlobalSettings();
|
||||||
|
|
||||||
|
/** Loads the upgrade palette and the per-protocol palettes.
|
||||||
|
The aProtocolFolder is the path to the folder containing the per-protocol palettes. */
|
||||||
|
void LoadPalettes(const AString & aProtocolFolder);
|
||||||
|
|
||||||
/** Loads the worlds from settings.ini, creates the worldmap */
|
/** Loads the worlds from settings.ini, creates the worldmap */
|
||||||
void LoadWorlds(cDeadlockDetect & a_dd, cSettingsRepositoryInterface & a_Settings, bool a_IsNewIniFile);
|
void LoadWorlds(cDeadlockDetect & a_dd, cSettingsRepositoryInterface & a_Settings, bool a_IsNewIniFile);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user