Skip to content

Commit

Permalink
Added temporary block type mapping for 1.13+ protocols.
Browse files Browse the repository at this point in the history
  • Loading branch information
madmaxoft committed Jan 7, 2020
1 parent e234fbd commit 4aef80b
Show file tree
Hide file tree
Showing 16 changed files with 375 additions and 76 deletions.
1 change: 1 addition & 0 deletions Server/Install/UnixExecutables.list
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Cuberite
Plugins
Prefabs
Protocol
webadmin
BACKERS
brewing.txt
Expand Down
1 change: 1 addition & 0 deletions Server/Install/WindowsExecutables.list
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Cuberite.exe
*.dll
Plugins
Prefabs
Protocol
webadmin
BACKERS
brewing.txt
Expand Down
30 changes: 21 additions & 9 deletions Server/Protocol/UpgradeBlockTypePalette.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CommonPrefix minecraft:
1 4 polished_diorite
1 5 andesite
1 6 polished_andesite
2 0 grass_block
2 0 grass_block snowy false
3 0 dirt
3 1 coarse_dirt
3 2 podzol
Expand Down Expand Up @@ -38,14 +38,26 @@ CommonPrefix minecraft:
14 0 gold_ore
15 0 iron_ore
16 0 coal_ore
17 0 oak_log
17 1 spruce_log
17 2 birch_log
17 3 jungle_log
18 0 oak_leaves
18 1 spruce_leaves
18 2 birch_leaves
18 3 jungle_leaves
17 0 oak_log axis y
17 1 spruce_log axis y
17 2 birch_log axis y
17 3 jungle_log axis y
17 4 oak_log axis x
17 5 spruce_log axis x
17 6 birch_log axis x
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 1 wet_sponge
20 0 glass
Expand Down
2 changes: 2 additions & 0 deletions src/Protocol/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SET (SRCS
Protocol_1_11.cpp
Protocol_1_12.cpp
Protocol_1_13.cpp
ProtocolPalettes.cpp
ProtocolRecognizer.cpp
)

Expand All @@ -28,6 +29,7 @@ SET (HDRS
Protocol_1_11.h
Protocol_1_12.h
Protocol_1_13.h
ProtocolPalettes.h
ProtocolRecognizer.h
)

Expand Down
33 changes: 10 additions & 23 deletions src/Protocol/ChunkDataSerializer.cpp
Original file line number Diff line number Diff line change
@@ -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 "ChunkDataSerializer.h"
#include "zlib/zlib.h"
Expand Down Expand Up @@ -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);
if (itr != m_Serializations.end())
Expand All @@ -63,11 +56,10 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int
AString data;
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_4: Serialize110(data, a_ChunkX, a_ChunkZ); break;
case RELEASE_1_13: Serialize393(data, a_ChunkX, a_ChunkZ); break;
// TODO: Other protocol versions may serialize the data differently; implement here
case RELEASE_1_13: Serialize393(data, a_ChunkX, a_ChunkZ, a_BlockTypeMap); break;

default:
{
Expand Down Expand Up @@ -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!

ASSERT(!a_BlockTypeMap.empty()); // We need a protocol-specific translation map

// Create the packet:
cByteBuffer Packet(512 KiB);
Packet.WriteVarInt32(0x22); // Packet id (Chunk Data packet)
Expand Down Expand Up @@ -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++)
{
UInt64 Value = a_Section.m_BlockTypes[Index];
/*
if (Index % 2 == 0)
{
Value |= a_Section.m_BlockMetas[Index / 2] & 0x0f;
}
else
{
Value |= a_Section.m_BlockMetas[Index / 2] >> 4;
}
*/
UInt32 blockType = a_Section.m_BlockTypes[Index];
UInt32 blockMeta = (a_Section.m_BlockMetas[Index / 2] >> ((Index % 2) * 4)) & 0x0f;
auto itr = a_BlockTypeMap.find(blockType * 16 | blockMeta);
UInt64 Value = (itr == a_BlockTypeMap.end()) ? 0 :itr->second;
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.
Expand Down
54 changes: 33 additions & 21 deletions src/Protocol/ChunkDataSerializer.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@

// 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
#pragma once

#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
{
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:
enum
{
Expand All @@ -41,7 +26,34 @@ class cChunkDataSerializer
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
} ;


Expand Down
5 changes: 5 additions & 0 deletions src/Protocol/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ class 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.
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. */
Expand Down
107 changes: 107 additions & 0 deletions src/Protocol/ProtocolPalettes.cpp
Original file line number Diff line number Diff line change
@@ -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)
{
}
Loading

0 comments on commit 4aef80b

Please sign in to comment.