summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CONTRIBUTORS1
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua4
-rw-r--r--Server/Plugins/APIDump/SettingUpLuaLanguageServer.html42
-rw-r--r--Server/Plugins/APIDump/Static/vscode_lua_addon.pngbin0 -> 72014 bytes
-rw-r--r--Server/Plugins/APIDump/Static/vscode_lua_settings.pngbin0 -> 24284 bytes
-rw-r--r--Server/Plugins/APIDump/_preload.lua22
-rw-r--r--Server/Plugins/APIDump/lualanguageserver.lua223
-rw-r--r--Server/Plugins/APIDump/main_APIDump.lua7
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.cpp7
-rw-r--r--src/ByteBuffer.cpp78
-rw-r--r--src/Endianness.h183
-rw-r--r--src/Protocol/ChunkDataSerializer.cpp2
-rw-r--r--src/StringUtils.cpp59
-rw-r--r--src/StringUtils.h14
-rw-r--r--src/WorldStorage/FastNBT.cpp55
-rw-r--r--src/WorldStorage/FastNBT.h13
-rw-r--r--src/WorldStorage/FireworksSerializer.cpp4
-rw-r--r--src/WorldStorage/WSSAnvil.cpp2
18 files changed, 503 insertions, 213 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 0a599bd30..1ef873ea8 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -9,6 +9,7 @@ as provided in the LICENSE file.
9caihezi
AirOne01
Altenius
+ashquarky
BasedDoge (Donated AlchemistVillage prefabs)
bearbin (Alexander Harkness)
beeduck
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index 0bcbca848..54a8d4e4f 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -19247,6 +19247,10 @@ end
Title = "Setting up the ZeroBrane Studio Lua IDE",
},
{
+ FileName = "SettingUpLuaLanguageServer.html",
+ Title = "Setting up Lua-Language-Server (VSCode/Emacs)"
+ },
+ {
FileName = "UsingChunkStays.html",
Title = "Using ChunkStays",
},
diff --git a/Server/Plugins/APIDump/SettingUpLuaLanguageServer.html b/Server/Plugins/APIDump/SettingUpLuaLanguageServer.html
new file mode 100644
index 000000000..ffe79aed9
--- /dev/null
+++ b/Server/Plugins/APIDump/SettingUpLuaLanguageServer.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+
+<html>
+ <head>
+ <title>Cuberite - Setting up the Lua-Language-Server (VSCode)</title>
+ <link rel="canonical" href="https://api.cuberite.org/SettingUpLuaLanguageServer.html">
+ <link rel="stylesheet" type="text/css" href="main.css" />
+ <link rel="stylesheet" type="text/css" href="prettify.css" />
+ <script src="prettify.js"></script>
+ <script src="lang-lua.js"></script>
+ <meta charset="UTF-8">
+ </head>
+ <body>
+ <div id="content">
+ <h1>Setting up the Lua-Language-Server (VSCode)</h1>
+ <p>This article will explain how to configure an IDE that is able to use the <a href="https://github.com/LuaLS/lua-language-server">Lua-Language-Server</a>. This article will show how it's done using Visual Studio Code, but it should work with any IDE that supports language servers.</p>
+
+ <h2>About Language Servers</h2>
+
+ <p>IDE's in the past always implemented every programming language they supported on their own, it was baked in. Because of this everyone supported different features. With language servers this all changes. A single language server can be created with a community which can be shared across any number of IDE's which support the protocol. To learn more about language servers and IDE's that support them see <a href="https://langserver.org/">langserver.org</a></p>
+
+ <h2>First-time setup</h2>
+ <p>Visual Studio Code doesn't support Lua by default. Instead it has a marketplace where extensions can be downloaded from. In this example we're going to use the Lua extension by Sumneko who also created the language server.</p>
+
+ <img src="Static/vscode_lua_addon.png" />
+
+ <h3>Libraries</h3>
+ <p>The extension doesn't know the Cuberite API by default. The extension, or rather the language server, supports the inclusion of libraries. In order to generate the definitions required by the language server you have to activate the APIDump plugin in Cuberite which is included by default but not enabled. When the plugin is enabled the entire API can be exported by using the 'api' command in the console. Once this has completed there is a new folder next to the Cuberite executable called LLS.</p>
+ <p>In order to use these definition files you need to create a settings.json file in the plugin folder you're developing for. This file should be in a folder called '.vscode'. If it doesn't exist yet you have to create it yourself. There are two important settings to configure:
+ <ul>
+ <li><b>Lua.runtime.version</b> which has to be set to "Lua 5.1". Cuberite only supports Lua 5.1.</li>
+ <li><b>Lua.workspace.library</b> which is an array containing all libraries used in the project. In this case it needs to point to the newly generated definition files. If you're developing your plugin using the same Cuberite instance as where you generated the definitions using the APIDump plugin you can set this to "../../LLS/cuberite/library". If your definitions are on a different location you will have to point to it yourself. Absolute paths are also supported.</li>
+ </ul>
+ </p>
+
+ <p>After configuring your settings.json file would something like this:</p>
+ <img src="Static/vscode_lua_settings.png" />
+
+ <p>After saving the settings.json file the IDE should recognize Cuberite's API.</p>
+ </div>
+ </body>
+</html>
diff --git a/Server/Plugins/APIDump/Static/vscode_lua_addon.png b/Server/Plugins/APIDump/Static/vscode_lua_addon.png
new file mode 100644
index 000000000..109f220ce
--- /dev/null
+++ b/Server/Plugins/APIDump/Static/vscode_lua_addon.png
Binary files differ
diff --git a/Server/Plugins/APIDump/Static/vscode_lua_settings.png b/Server/Plugins/APIDump/Static/vscode_lua_settings.png
new file mode 100644
index 000000000..aee427c1e
--- /dev/null
+++ b/Server/Plugins/APIDump/Static/vscode_lua_settings.png
Binary files differ
diff --git a/Server/Plugins/APIDump/_preload.lua b/Server/Plugins/APIDump/_preload.lua
new file mode 100644
index 000000000..becc691c4
--- /dev/null
+++ b/Server/Plugins/APIDump/_preload.lua
@@ -0,0 +1,22 @@
+
+-- _preload.lua
+
+-- First thing executed when the plugin loads. Replaces the global environment (_G) with an empty table
+-- with __index set to the old environment. This way any function or variable that is created globally by the plugin
+-- won't be reported as new or undocumented.
+
+
+
+
+
+local newEnv, oldEnv = {}, _G
+local setmetatable = setmetatable
+for k, v in pairs(_G) do
+ newEnv[k] = v;
+ oldEnv[k] = nil;
+end
+_G = setmetatable(oldEnv, {__index = newEnv});
+
+
+
+
diff --git a/Server/Plugins/APIDump/lualanguageserver.lua b/Server/Plugins/APIDump/lualanguageserver.lua
new file mode 100644
index 000000000..2e1b86410
--- /dev/null
+++ b/Server/Plugins/APIDump/lualanguageserver.lua
@@ -0,0 +1,223 @@
+-- lualanguageserver.lua
+
+-- Implements the code for exporting definition files which can be used by a Lua-Language-Server
+
+
+
+
+
+--- Cleans up the name of a parameter so it can be used in a definition file
+--- Removes anything containing brackets and removes dashes and spaces.
+local function CleanupParameterName(paramName)
+ paramName = paramName:gsub("[%- ]", "")
+ :gsub("<.->.-</.->", '');
+ return paramName
+end
+
+
+
+
+
+--- Cleans up a description so it can be used in a definition file.
+--- Uses the standard cleanup function but also removes any newlines.
+local function CleanUpDescriptionLLS(a_Desc)
+ return CleanUpDescription(a_Desc)
+ :gsub("\n", " ")
+end
+
+
+
+
+
+--- Writes a list of methods into the specified file in LLS format
+local function WriteLLSMethods(f, a_NameSpace, a_Methods)
+ for _, func in ipairs(a_Methods or {}) do
+ f:write("\n---\n")
+ f:write("---", CleanUpDescriptionLLS(func.Notes or ""), "\n");
+ f:write("---\n");
+ local parameterList = {}
+ if (func.Params) then
+ local paramNr = 0;
+ for _, param in ipairs(func.Params) do
+ paramNr = paramNr + 1;
+ local paramName = CleanupParameterName(param.Name or ("param" .. paramNr));
+ if (paramName:find("%.%.%.")) then
+ paramName = "..."
+ end
+ table.insert(parameterList, paramName)
+ if (param.IsOptional and paramName ~= "...") then
+ paramName = paramName .. "?"
+ end
+
+ local paramType = param.Type;
+ if (paramType:find("%#")) then
+ paramType = paramType:match("%#(.+)");
+ end
+ f:write("---@param ", paramName, " ", paramType, "\n");
+ end
+ f:write("---\n");
+ end
+
+ if (func.Returns) then
+ for _, ret in ipairs(func.Returns) do
+ f:write("---@return ", ret.Type, "\n");
+ end
+ f:write("---\n");
+ end
+ local name = func.Name:find("constructor") and "__call" or func.Name;
+ name = name:find("operator") and "__meta" or name
+ local parameters = table.concat(parameterList, ", ");
+ f:write("function ")
+ if (a_NameSpace) then
+ f:write(a_NameSpace, ":")
+ end
+ f:write(name, "(", parameters, ") end\n\n");
+ end
+end
+
+
+
+
+
+--- Writes the list of constants. If the value is an enum the value is set from that enum.
+--- This is a bit of a hack because Cuberite exports allot of enums as a constant inside
+--- a class or global but documents them as if they are in their own table.
+local function WriteLLSConstants(f, a_NameSpace, a_Constants, a_Enum)
+ if (not a_Constants) then
+ return;
+ end
+
+ local prefix = ""
+ if (a_NameSpace) then
+ prefix = a_NameSpace .. ".";
+ end
+ for _, const in pairs(a_Constants) do
+ f:write(prefix)
+ if (a_Enum) then
+ f:write(const.Name, " = ", prefix, a_Enum, ".", const.Name, "\n")
+ else
+ local constValue = tostring(const.Value):match("[%w%d]+") or "nil";
+ f:write(const.Name, " = ", constValue, "\n")
+ end
+ end
+end
+
+
+
+
+
+--- Writes a list of constants into the specified file in LLS format
+local function WriteLLSEnums(f, a_NameSpace, a_ConstantGroups)
+ if (not a_ConstantGroups) then
+ return;
+ end
+
+ local prefix = "";
+ if (a_NameSpace) then
+ prefix = a_NameSpace .. "."
+ end
+ for _, group in pairs(a_ConstantGroups) do
+ f:write("---@enum ", group.Name, "\n");
+ f:write(prefix, group.Name, " = {\n")
+ for _, const in pairs(group.Constants) do
+ local constValue = tostring(const.Value):match("[%w%d]+") or "nil";
+ f:write("\t", const.Name, " = ", constValue, ",\n")
+ end
+ f:write("}\n")
+ WriteLLSConstants(f, a_NameSpace, group.Constants, group.Name);
+ end
+end
+
+
+
+
+
+--- Writes all the fields which a class has.
+---@param f file*
+---@param a_Variables table
+local function WriteLLSVariables(f, a_Variables)
+ for _, variable in ipairs(a_Variables or {}) do
+ f:write("---@field ", variable.Name)
+ if (variable.Type) then
+ local type = variable.Type:match("%w+")
+ f:write(" ", type)
+ end
+ if (variable.Notes) then
+ f:write(" ", variable.Notes)
+ end
+ f:write("\n");
+ end
+end
+
+
+
+
+
+--- Writes one Cuberite class definition into the specified file in LLS format
+local function WriteLLSClass(a_Class)
+ assert(type(a_Class) == "table")
+
+ local f = io.open("LLS/cuberite/library/" .. a_Class.Name .. ".lua", "w");
+ f:write("---@meta\n");
+ f:write("\n\n---\n---The ", a_Class.Name, " namespace\n");
+
+ local inherit = "";
+ if (a_Class.Inherits) then
+ inherit = ": " .. a_Class.Inherits.Name
+ end
+ f:write("---@class ", a_Class.Name, inherit, "\n");
+ WriteLLSVariables(f, a_Class.Variables);
+ for _, func in pairs(a_Class.Functions or {}) do
+ if (func.Name:find("constructor")) then
+ local parameters = {};
+ for _, param in ipairs(func.Parameters or {}) do
+ table.insert(parameters, param.Type);
+ end
+ f:write("---@operator call(", table.concat(parameters, ","), "):" .. a_Class.Name, "\n")
+ end
+ end
+ f:write("", a_Class.Name, " = {}\n");
+
+ -- Export methods and constants:
+ WriteLLSEnums(f, a_Class.Name, a_Class.ConstantGroups);
+ WriteLLSConstants(f, a_Class.Name, a_Class.Constants);
+ WriteLLSMethods(f, a_Class.Name, a_Class.Functions);
+
+ f:close();
+end
+
+
+
+
+
+--- Dumps the entire API table into a file in the LLS format
+function DumpAPILLS(a_API)
+ LOG("Dumping LLS API description...")
+ cFile:CreateFolderRecursive("LLS/cuberite/library");
+
+ -- Export each class except Globals, store those aside:
+ local Globals
+ for _, cls in ipairs(a_API) do
+ if (cls.Name ~= "Globals") then
+ WriteLLSClass(cls)
+ else
+ Globals = cls
+ end
+ end
+
+ -- Export the globals:
+ if (Globals) then
+ local f = io.open("LLS/cuberite/library/Globals.lua", "w");
+ f:write("---@meta\n\n");
+ WriteLLSMethods(f, nil, Globals.Functions)
+ WriteLLSEnums(f, nil, Globals.ConstantGroups)
+ f:close();
+ end
+
+ -- Finish the file:
+ LOG("LLS API dumped...")
+end
+
+
+
+
diff --git a/Server/Plugins/APIDump/main_APIDump.lua b/Server/Plugins/APIDump/main_APIDump.lua
index 735a6ec05..5d6f5255f 100644
--- a/Server/Plugins/APIDump/main_APIDump.lua
+++ b/Server/Plugins/APIDump/main_APIDump.lua
@@ -136,7 +136,7 @@ local function CreateAPITables()
return res;
end
- for i, v in pairs(_G) do
+ for i, v in pairs(getmetatable(_G).__index) do
if (
(v ~= _G) and -- don't want the global namespace
(v ~= _G.packages) and -- don't want any packages
@@ -1473,7 +1473,7 @@ end
--- Returns the string with extra tabs and CR/LFs removed
-local function CleanUpDescription(a_Desc)
+function CleanUpDescription(a_Desc)
-- Get rid of indent and newlines, normalize whitespace:
local res = a_Desc:gsub("[\n\t]", "")
res = a_Desc:gsub("%s%s+", " ")
@@ -1858,6 +1858,9 @@ local function DumpApi()
-- Dump all available API objects in format used by ZeroBraneStudio API descriptions:
DumpAPIZBS(API)
+ -- Dump all available API objects in format used by Lua-Language-Server API descriptions:
+ DumpAPILLS(API);
+
-- Export the API in a format used by LuaCheck
DumpLuaCheck(API)
diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp
index ea3346f04..120b72474 100644
--- a/Tools/QtBiomeVisualiser/ChunkSource.cpp
+++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp
@@ -5,6 +5,7 @@
#include "src/StringCompression.h"
#include "src/WorldStorage/FastNBT.h"
#include "src/IniFile.h"
+#include "src/Endianness.h"
@@ -143,7 +144,7 @@ public:
// Get the real data size:
const char * chunkData = m_FileData.data() + chunkOffset * 4096;
- UInt32 chunkSize = GetBEInt(chunkData);
+ UInt32 chunkSize = NetworkBufToHost(chunkData);
if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors))
{
// Bad data, bail out
@@ -181,7 +182,7 @@ protected:
const char * hdr = m_FileData.data();
for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
{
- m_Header[i] = GetBEInt(hdr + 4 * i);
+ m_Header[i] = NetworkBufToHost(hdr + 4 * i);
}
m_IsValid = true;
}
@@ -241,7 +242,7 @@ void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk
const char * beBiomes = nbt.GetData(mcsBiomes);
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
{
- biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
+ biomeMap[i] = (EMCSBiome)NetworkBufToHost<Int32>(beBiomes + 4 * i);
}
a_DestChunk.setBiomes(biomeMap);
return;
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index 8121fc3ef..c5fe0a7c0 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -285,10 +285,9 @@ bool cByteBuffer::ReadBEInt16(Int16 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(2);
- UInt16 val;
- ReadBuf(&val, 2);
- val = ntohs(val);
- memcpy(&a_Value, &val, 2);
+ Bytes<Int16> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<Int16>(bytes);
return true;
}
@@ -301,8 +300,9 @@ bool cByteBuffer::ReadBEUInt16(UInt16 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(2);
- ReadBuf(&a_Value, 2);
- a_Value = ntohs(a_Value);
+ Bytes<UInt16> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<UInt16>(bytes);
return true;
}
@@ -315,10 +315,9 @@ bool cByteBuffer::ReadBEInt32(Int32 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(4);
- UInt32 val;
- ReadBuf(&val, 4);
- val = ntohl(val);
- memcpy(&a_Value, &val, 4);
+ Bytes<Int32> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<Int32>(bytes);
return true;
}
@@ -331,8 +330,9 @@ bool cByteBuffer::ReadBEUInt32(UInt32 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(4);
- ReadBuf(&a_Value, 4);
- a_Value = ntohl(a_Value);
+ Bytes<UInt32> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<UInt32>(bytes);
return true;
}
@@ -345,8 +345,9 @@ bool cByteBuffer::ReadBEInt64(Int64 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(8);
- ReadBuf(&a_Value, 8);
- a_Value = NetworkToHostLong8(&a_Value);
+ Bytes<Int64> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<Int64>(bytes);
return true;
}
@@ -359,8 +360,9 @@ bool cByteBuffer::ReadBEUInt64(UInt64 & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(8);
- ReadBuf(&a_Value, 8);
- a_Value = NetworkToHostULong8(&a_Value);
+ Bytes<UInt64> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<UInt64>(bytes);
return true;
}
@@ -373,8 +375,9 @@ bool cByteBuffer::ReadBEFloat(float & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(4);
- ReadBuf(&a_Value, 4);
- a_Value = NetworkToHostFloat4(&a_Value);
+ Bytes<float> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<float>(bytes);
return true;
}
@@ -387,8 +390,9 @@ bool cByteBuffer::ReadBEDouble(double & a_Value)
CHECK_THREAD
CheckValid();
NEEDBYTES(8);
- ReadBuf(&a_Value, 8);
- a_Value = NetworkToHostDouble8(&a_Value);
+ Bytes<double> bytes;
+ ReadBuf(bytes.data(), bytes.size());
+ a_Value = NetworkToHost<double>(bytes);
return true;
}
@@ -629,10 +633,8 @@ bool cByteBuffer::WriteBEInt16(Int16 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(2);
- UInt16 val;
- memcpy(&val, &a_Value, 2);
- val = htons(val);
- return WriteBuf(&val, 2);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -644,8 +646,8 @@ bool cByteBuffer::WriteBEUInt16(UInt16 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(2);
- a_Value = htons(a_Value);
- return WriteBuf(&a_Value, 2);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -657,8 +659,8 @@ bool cByteBuffer::WriteBEInt32(Int32 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(4);
- UInt32 Converted = HostToNetwork4(&a_Value);
- return WriteBuf(&Converted, 4);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -670,8 +672,8 @@ bool cByteBuffer::WriteBEUInt32(UInt32 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(4);
- UInt32 Converted = HostToNetwork4(&a_Value);
- return WriteBuf(&Converted, 4);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -683,8 +685,8 @@ bool cByteBuffer::WriteBEInt64(Int64 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(8);
- UInt64 Converted = HostToNetwork8(&a_Value);
- return WriteBuf(&Converted, 8);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -696,8 +698,8 @@ bool cByteBuffer::WriteBEUInt64(UInt64 a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(8);
- UInt64 Converted = HostToNetwork8(&a_Value);
- return WriteBuf(&Converted, 8);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -709,8 +711,8 @@ bool cByteBuffer::WriteBEFloat(float a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(4);
- UInt32 Converted = HostToNetwork4(&a_Value);
- return WriteBuf(&Converted, 4);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
@@ -722,8 +724,8 @@ bool cByteBuffer::WriteBEDouble(double a_Value)
CHECK_THREAD
CheckValid();
PUTBYTES(8);
- UInt64 Converted = HostToNetwork8(&a_Value);
- return WriteBuf(&Converted, 8);
+ auto Converted = HostToNetwork(a_Value);
+ return WriteBuf(Converted.data(), Converted.size());
}
diff --git a/src/Endianness.h b/src/Endianness.h
index 0e8bc8e99..c75698587 100644
--- a/src/Endianness.h
+++ b/src/Endianness.h
@@ -1,86 +1,143 @@
-
#pragma once
-#undef ntohll
-#define ntohll(x) (((static_cast<UInt64>(ntohl(static_cast<UInt32>(x)))) << 32) + ntohl(x >> 32))
-
-
-
-
-
-// Changes endianness
-inline UInt64 HostToNetwork8(const void * a_Value)
+#include <array>
+template <typename T>
+using Bytes = std::array<std::byte, sizeof(T)>;
+
+// bit_cast used for going between ulong, float, etc. It's a new C++20 feature
+#ifdef __cpp_lib_bit_cast
+#include <bit>
+using std::bit_cast;
+
+// Fallback in case we're using C++17
+#else
+// bit-for-bit convert one type to another. In C++ the only non-UB way to do this is *memcpy*. Nearly every other
+// option is a strict aliasing violation.
+template<class To, class From>
+std::enable_if_t<
+ sizeof(To) == sizeof(From),
+ To>
+bit_cast(const From &src) noexcept
{
- UInt64 buf;
- memcpy( &buf, a_Value, sizeof( buf));
- buf = (( ( static_cast<UInt64>(htonl(static_cast<UInt32>(buf)))) << 32) + htonl(buf >> 32));
- return buf;
+ To dst;
+ std::memcpy(&dst, &src, sizeof(To));
+ return dst;
}
+#endif
-
-
-
-inline UInt32 HostToNetwork4(const void * a_Value)
+/** Converts a 16-bit host integer or float value to bytes in big-endian (Network) order.
+@tparam Value The host 16-bit type (Int16, UInt16). Usually inferred.
+@param a_Value The input integer or float value.
+@return The resulting bytes. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 2, bool> = true>
+inline Bytes<Value> HostToNetwork(Value a_Value)
{
- UInt32 buf;
- memcpy( &buf, a_Value, sizeof( buf));
- buf = ntohl( buf);
- return buf;
+ UInt16 Bits = bit_cast<UInt16>(a_Value);
+ return
+ {
+ std::byte(Bits >> 8),
+ std::byte(Bits)
+ };
}
-
-
-
-
-inline double NetworkToHostDouble8(const void * a_Value)
+/** Converts a 32-bit host integer or float value to bytes in big-endian (Network) order.
+@tparam Value The host 32-bit type (Int32, UInt32, float). Usually inferred.
+@param a_Value The input integer or float value.
+@return The resulting bytes. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 4, bool> = true>
+inline Bytes<Value> HostToNetwork(Value a_Value)
{
- UInt64 buf = 0;
- memcpy(&buf, a_Value, 8);
- buf = ntohll(buf);
- double x;
- memcpy(&x, &buf, sizeof(double));
- return x;
+ UInt32 Bits = bit_cast<UInt32>(a_Value);
+ return
+ {
+ std::byte(Bits >> 24),
+ std::byte(Bits >> 16),
+ std::byte(Bits >> 8),
+ std::byte(Bits)
+ };
}
-
-
-
-
-inline Int64 NetworkToHostLong8(const void * a_Value)
+/** Converts a 64-bit host integer or float value to bytes in big-endian (Network) order.
+@tparam Value The host 64-bit type (Int64, UInt64, double). Usually inferred.
+@param a_Value The input integer or float value.
+@return The resulting bytes. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 8, bool> = true>
+inline Bytes<Value> HostToNetwork(Value a_Value)
{
- UInt64 buf;
- memcpy(&buf, a_Value, 8);
- buf = ntohll(buf);
- return *reinterpret_cast<Int64 *>(&buf);
+ UInt64 Bits = bit_cast<UInt64>(a_Value);
+ return
+ {
+ std::byte(Bits >> 56),
+ std::byte(Bits >> 48),
+ std::byte(Bits >> 40),
+ std::byte(Bits >> 32),
+ std::byte(Bits >> 24),
+ std::byte(Bits >> 16),
+ std::byte(Bits >> 8),
+ std::byte(Bits)
+ };
}
-
-
-
-
-inline UInt64 NetworkToHostULong8(const void * a_Value)
+/** Reads a 16-bit integer or float value from big-endian (Network) bytes.
+@tparam Value The desired 16-bit type (Int16, UInt16)
+@param a_Value The input bytes.
+@return The resulting integer or float value. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 2, bool> = true>
+inline Value NetworkToHost(Bytes<Value> a_Value)
{
- UInt64 buf;
- memcpy(&buf, a_Value, 8);
- buf = ntohll(buf);
- return buf;
+ UInt16 val = UInt16(
+ UInt16(a_Value[0]) << 8 |
+ UInt16(a_Value[1]));
+ return bit_cast<Value>(val);
}
-
-
-
-
-inline float NetworkToHostFloat4(const void * a_Value)
+/** Reads a 32-bit integer or float value from big-endian (Network) bytes.
+@tparam Value The desired 32-bit type (Int32, UInt32, float)
+@param a_Value The input bytes.
+@return The resulting integer or float value. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 4, bool> = true>
+inline Value NetworkToHost(Bytes<Value> a_Value)
{
- UInt32 buf;
- float x;
- memcpy(&buf, a_Value, 4);
- buf = ntohl(buf);
- memcpy(&x, &buf, sizeof(float));
- return x;
+ UInt32 val = UInt32(
+ UInt32(a_Value[0]) << 24 |
+ UInt32(a_Value[1]) << 16 |
+ UInt32(a_Value[2]) << 8 |
+ UInt32(a_Value[3]));
+ return bit_cast<Value>(val);
}
+/** Reads a 64-bit integer or float value from big-endian (Network) bytes.
+@tparam Value The desired 64-bit type (Int64, UInt64, double)
+@param a_Value The input bytes.
+@return The resulting integer or float value. */
+template<typename Value, std::enable_if_t<sizeof(Value) == 8, bool> = true>
+inline Value NetworkToHost(Bytes<Value> a_Value)
+{
+ UInt64 val = UInt64(
+ UInt64(a_Value[0]) << 56 |
+ UInt64(a_Value[1]) << 48 |
+ UInt64(a_Value[2]) << 40 |
+ UInt64(a_Value[3]) << 32 |
+ UInt64(a_Value[4]) << 24 |
+ UInt64(a_Value[5]) << 16 |
+ UInt64(a_Value[6]) << 8 |
+ UInt64(a_Value[7]));
+ return bit_cast<Value>(val);
+}
+/** Reads an integer or float type from its big-endian (Network) bytes.
+@tparam Value The desired result type (Int16 / 32 / 64, UInt16 / 32 / 64, float, double).
+@param a_Mem A pointer to the first input byte. Length is inferred from the result type.
+@return The resulting integer or float value.
-
+Consider using NetworkToHost when the data is owned since it provides additional type safety (length is known). */
+template<typename Value>
+inline Value NetworkBufToHost(const std::byte* a_Mem)
+{
+ // Copy unfortunately needed to add the length information required by the rest of the API.
+ // Gets completely optimised out in my testing.
+ Bytes<Value> bytes;
+ std::copy(a_Mem, a_Mem + sizeof(Value), bytes.begin());
+ return NetworkToHost<Value>(bytes);
+}
diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp
index cfabc6e31..6b5553ee7 100644
--- a/src/Protocol/ChunkDataSerializer.cpp
+++ b/src/Protocol/ChunkDataSerializer.cpp
@@ -502,7 +502,7 @@ inline void cChunkDataSerializer::Serialize477(const int a_ChunkX, const int a_C
// Write each chunk section...
ChunkDef_ForEachSection(a_BlockData, a_LightData,
{
- m_Packet.WriteBEInt16(-1);
+ m_Packet.WriteBEInt16(ChunkBlockData::SectionBlockCount); // a temp fix to make sure sections don't disappear
m_Packet.WriteBEUInt8(BitsPerEntry);
m_Packet.WriteVarInt32(static_cast<UInt32>(ChunkSectionDataArraySize));
WriteBlockSectionSeamless<&Palette477>(Blocks, Metas, BitsPerEntry);
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index e6d5e3812..cf4a69319 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -5,13 +5,9 @@
#include "Globals.h"
+#include "Endianness.h"
#include "fmt/printf.h"
-#ifdef _MSC_VER
- // Under MSVC, link to WinSock2 (needed by RawBEToUTF8's byteswapping)
- #pragma comment(lib, "ws2_32.lib")
-#endif
-
@@ -339,13 +335,14 @@ void ReplaceURL(AString & iHayStack, const AString & iNeedle, const AString & iR
-AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8)
+AString & RawBEUTF16ToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8)
{
a_UTF8.clear();
a_UTF8.reserve(3 * a_NumShorts / 2); // a quick guess of the resulting size
for (size_t i = 0; i < a_NumShorts; i++)
{
- a_UTF8.append(UnicodeCharToUtf8(GetBEUShort(&a_RawData[i * 2])));
+ auto UTF16 = NetworkBufToHost<UInt16>(reinterpret_cast<const std::byte *>(&a_RawData[i * 2]));
+ a_UTF8.append(UnicodeCharToUtf8(UTF16));
}
return a_UTF8;
}
@@ -946,54 +943,6 @@ AString Base64Encode(const AString & a_Input)
-short GetBEShort(const std::byte * const a_Mem)
-{
- return static_cast<short>(
- (static_cast<short>(a_Mem[0]) << 8) |
- static_cast<short>(a_Mem[1])
- );
-}
-
-
-
-
-
-unsigned short GetBEUShort(const char * a_Mem)
-{
- const Byte * Bytes = reinterpret_cast<const Byte *>(a_Mem);
- return static_cast<unsigned short>((Bytes[0] << 8) | Bytes[1]);
-}
-
-
-
-
-
-int GetBEInt(const std::byte * const a_Mem)
-{
- return
- (static_cast<int>(a_Mem[0]) << 24) |
- (static_cast<int>(a_Mem[1]) << 16) |
- (static_cast<int>(a_Mem[2]) << 8) |
- static_cast<int>(a_Mem[3])
- ;
-}
-
-
-
-
-
-void SetBEInt(std::byte * a_Mem, Int32 a_Value)
-{
- a_Mem[0] = std::byte(a_Value >> 24);
- a_Mem[1] = std::byte((a_Value >> 16) & 0xff);
- a_Mem[2] = std::byte((a_Value >> 8) & 0xff);
- a_Mem[3] = std::byte(a_Value & 0xff);
-}
-
-
-
-
-
bool SplitZeroTerminatedStrings(const AString & a_Strings, AStringVector & a_Output)
{
a_Output.clear();
diff --git a/src/StringUtils.h b/src/StringUtils.h
index efb6a8566..f096d9b66 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -67,7 +67,7 @@ extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AS
extern void ReplaceURL(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith);
/** Converts a stream of BE shorts into UTF-8 string; returns a_UTF8. */
-extern AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8);
+extern AString & RawBEUTF16ToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8);
/** Converts a unicode character to its UTF8 representation. */
extern AString UnicodeCharToUtf8(unsigned a_UnicodeChar);
@@ -101,18 +101,6 @@ extern AString Base64Decode(const AString & a_Base64String); // Exported manual
/** Encodes a string into Base64 */
extern AString Base64Encode(const AString & a_Input); // Exported manually due to embedded NULs and extra parameter
-/** Reads two bytes from the specified memory location and interprets them as BigEndian short */
-extern short GetBEShort(const std::byte * a_Mem);
-
-/** Reads two bytes from the specified memory location and interprets them as BigEndian unsigned short */
-extern unsigned short GetBEUShort(const char * a_Mem);
-
-/** Reads four bytes from the specified memory location and interprets them as BigEndian int */
-extern int GetBEInt(const std::byte * a_Mem);
-
-/** Writes four bytes to the specified memory location so that they interpret as BigEndian int */
-extern void SetBEInt(std::byte * a_Mem, Int32 a_Value);
-
/** Splits a string that has embedded \0 characters, on those characters.
a_Output is first cleared and then each separate string is pushed back into a_Output.
Returns true if there are at least two strings in a_Output (there was at least one \0 separator). */
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index df93e21e4..030300387 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -189,7 +189,7 @@ eNBTParseError cParsedNBT::ReadString(size_t & a_StringStart, size_t & a_StringL
{
NEEDBYTES(2, eNBTParseError::npStringMissingLength);
a_StringStart = m_Pos + 2;
- a_StringLen = static_cast<size_t>(GetBEShort(m_Data.data() + m_Pos));
+ a_StringLen = static_cast<size_t>(NetworkBufToHost<UInt16>(m_Data.data() + m_Pos));
NEEDBYTES(2 + a_StringLen, eNBTParseError::npStringInvalidLength);
m_Pos += 2 + a_StringLen;
return eNBTParseError::npSuccess;
@@ -247,7 +247,7 @@ eNBTParseError cParsedNBT::ReadList(eTagType a_ChildrenType)
// Read the count:
NEEDBYTES(4, eNBTParseError::npListMissingLength);
- int Count = GetBEInt(m_Data.data() + m_Pos);
+ int Count = NetworkBufToHost<int>(m_Data.data() + m_Pos);
m_Pos += 4;
auto MinChildSize = GetMinTagSize(a_ChildrenType);
if ((Count < 0) || (Count > static_cast<int>((m_Data.size() - m_Pos) / MinChildSize)))
@@ -311,7 +311,7 @@ eNBTParseError cParsedNBT::ReadTag(void)
case TAG_ByteArray:
{
NEEDBYTES(4, eNBTParseError::npArrayMissingLength);
- int len = GetBEInt(m_Data.data() + m_Pos);
+ int len = NetworkBufToHost<int>(m_Data.data() + m_Pos);
m_Pos += 4;
if (len < 0)
{
@@ -343,7 +343,7 @@ eNBTParseError cParsedNBT::ReadTag(void)
case TAG_IntArray:
{
NEEDBYTES(4, eNBTParseError::npArrayMissingLength);
- int len = GetBEInt(m_Data.data() + m_Pos);
+ int len = NetworkBufToHost<int>(m_Data.data() + m_Pos);
m_Pos += 4;
if (len < 0)
{
@@ -539,7 +539,8 @@ void cFastNBTWriter::EndList(void)
ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);
// Update the list count:
- SetBEInt(m_Result.data() + m_Stack[m_CurrentStack].m_Pos, m_Stack[m_CurrentStack].m_Count);
+ auto Value = HostToNetwork(m_Stack[m_CurrentStack].m_Count);
+ std::copy(Value.begin(), Value.end(), m_Result.data() + m_Stack[m_CurrentStack].m_Pos);
--m_CurrentStack;
}
@@ -561,8 +562,8 @@ void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
{
TagCommon(a_Name, TAG_Short);
- UInt16 Value = htons(static_cast<UInt16>(a_Value));
- m_Result.append(reinterpret_cast<const std::byte *>(&Value), 2);
+ auto Value = HostToNetwork(a_Value);
+ m_Result.append(Value.begin(), Value.end());
}
@@ -572,8 +573,8 @@ void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
{
TagCommon(a_Name, TAG_Int);
- UInt32 Value = htonl(static_cast<UInt32>(a_Value));
- m_Result.append(reinterpret_cast<const std::byte *>(&Value), 4);
+ auto Value = HostToNetwork(a_Value);
+ m_Result.append(Value.begin(), Value.end());
}
@@ -583,8 +584,8 @@ void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
{
TagCommon(a_Name, TAG_Long);
- UInt64 Value = HostToNetwork8(&a_Value);
- m_Result.append(reinterpret_cast<const std::byte *>(&Value), 8);
+ auto Value = HostToNetwork(a_Value);
+ m_Result.append(Value.begin(), Value.end());
}
@@ -594,8 +595,8 @@ void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
{
TagCommon(a_Name, TAG_Float);
- UInt32 Value = HostToNetwork4(&a_Value);
- m_Result.append(reinterpret_cast<const std::byte *>(&Value), 4);
+ auto Value = HostToNetwork(a_Value);
+ m_Result.append(Value.begin(), Value.end());
}
@@ -605,8 +606,8 @@ void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
{
TagCommon(a_Name, TAG_Double);
- UInt64 Value = HostToNetwork8(&a_Value);
- m_Result.append(reinterpret_cast<const std::byte *>(&Value), 8);
+ auto Value = HostToNetwork(a_Value);
+ m_Result.append(Value.begin(), Value.end());
}
@@ -616,8 +617,8 @@ void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
void cFastNBTWriter::AddString(const AString & a_Name, const std::string_view a_Value)
{
TagCommon(a_Name, TAG_String);
- const UInt16 Length = htons(static_cast<UInt16>(a_Value.size()));
- m_Result.append(reinterpret_cast<const std::byte *>(&Length), sizeof(Length));
+ auto Length = HostToNetwork(static_cast<UInt16>(a_Value.size()));
+ m_Result.append(Length.begin(), Length.end());
m_Result.append({ reinterpret_cast<const std::byte *>(a_Value.data()), a_Value.size() });
}
@@ -628,8 +629,8 @@ void cFastNBTWriter::AddString(const AString & a_Name, const std::string_view a_
void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_ByteArray);
- UInt32 len = htonl(static_cast<UInt32>(a_NumElements));
- m_Result.append(reinterpret_cast<const std::byte *>(&len), 4);
+ auto Length = HostToNetwork(static_cast<UInt32>(a_NumElements));
+ m_Result.append(Length.begin(), Length.end());
m_Result.append(reinterpret_cast<const std::byte *>(a_Value), a_NumElements);
}
@@ -640,8 +641,8 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value,
void cFastNBTWriter::AddByteArray(const AString & a_Name, size_t a_NumElements, unsigned char a_Value)
{
TagCommon(a_Name, TAG_ByteArray);
- UInt32 len = htonl(static_cast<UInt32>(a_NumElements));
- m_Result.append(reinterpret_cast<const std::byte *>(&len), 4);
+ auto Length = HostToNetwork(static_cast<UInt32>(a_NumElements));
+ m_Result.append(Length.begin(), Length.end());
m_Result.append(a_NumElements, std::byte(a_Value));
}
@@ -652,18 +653,18 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, size_t a_NumElements,
void cFastNBTWriter::AddIntArray(const AString & a_Name, const Int32 * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_IntArray);
- UInt32 len = htonl(static_cast<UInt32>(a_NumElements));
+ auto Length = HostToNetwork(static_cast<UInt32>(a_NumElements));
size_t cap = m_Result.capacity();
size_t size = m_Result.length();
if ((cap - size) < (4 + a_NumElements * 4))
{
m_Result.reserve(size + 4 + (a_NumElements * 4));
}
- m_Result.append(reinterpret_cast<const std::byte *>(&len), sizeof(len));
+ m_Result.append(Length.begin(), Length.end());
for (size_t i = 0; i < a_NumElements; i++)
{
- UInt32 Element = htonl(static_cast<UInt32>(a_Value[i]));
- m_Result.append(reinterpret_cast<const std::byte *>(&Element), sizeof(Element));
+ auto Element = HostToNetwork(a_Value[i]);
+ m_Result.append(Element.begin(), Element.end());
}
}
@@ -684,7 +685,7 @@ void cFastNBTWriter::Finish(void)
void cFastNBTWriter::WriteString(const std::string_view a_Data)
{
// TODO check size <= short max
- UInt16 Len = htons(static_cast<unsigned short>(a_Data.size()));
- m_Result.append(reinterpret_cast<const std::byte *>(&Len), sizeof(Len));
+ auto Length = HostToNetwork(static_cast<UInt16>(a_Data.size()));
+ m_Result.append(Length.begin(), Length.end());
m_Result.append(reinterpret_cast<const std::byte *>(a_Data.data()), a_Data.size());
}
diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h
index d9c388179..b2eb851d7 100644
--- a/src/WorldStorage/FastNBT.h
+++ b/src/WorldStorage/FastNBT.h
@@ -227,21 +227,21 @@ public:
inline Int16 GetShort(int a_Tag) const
{
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Short);
- return GetBEShort(GetData(a_Tag));
+ return NetworkBufToHost<Int16>(GetData(a_Tag));
}
/** Returns the value stored in an Int tag. Not valid for any other tag type. */
inline Int32 GetInt(int a_Tag) const
{
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Int);
- return GetBEInt(GetData(a_Tag));
+ return NetworkBufToHost<Int32>(GetData(a_Tag));
}
/** Returns the value stored in a Long tag. Not valid for any other tag type. */
inline Int64 GetLong(int a_Tag) const
{
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Long);
- return NetworkToHostLong8(GetData(a_Tag));
+ return NetworkBufToHost<Int64>(GetData(a_Tag));
}
/** Returns the value stored in a Float tag. Not valid for any other tag type. */
@@ -256,10 +256,7 @@ public:
UNUSED_VAR(Check1);
UNUSED_VAR(Check2);
- Int32 i = GetBEInt(GetData(a_Tag));
- float f;
- memcpy(&f, &i, sizeof(f));
- return f;
+ return NetworkBufToHost<float>(GetData(a_Tag));
}
/** Returns the value stored in a Double tag. Not valid for any other tag type. */
@@ -273,7 +270,7 @@ public:
UNUSED_VAR(Check2);
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Double);
- return NetworkToHostDouble8(GetData(a_Tag));
+ return NetworkBufToHost<double>(GetData(a_Tag));
}
/** Returns the value stored in a String tag. Not valid for any other tag type. */
diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp
index f0fe7e48e..6616196e2 100644
--- a/src/WorldStorage/FireworksSerializer.cpp
+++ b/src/WorldStorage/FireworksSerializer.cpp
@@ -108,7 +108,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
const auto * ColourData = (a_NBT.GetData(explosiontag));
for (size_t i = 0; i < DataLength; i += 4)
{
- a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i));
+ a_FireworkItem.m_Colours.push_back(NetworkBufToHost<Int32>(ColourData + i));
}
}
else if (ExplosionName == "FadeColors")
@@ -124,7 +124,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
const auto * FadeColourData = (a_NBT.GetData(explosiontag));
for (size_t i = 0; i < DataLength; i += 4)
{
- a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i));
+ a_FireworkItem.m_FadeColours.push_back(NetworkBufToHost<Int32>(FadeColourData + i));
}
}
}
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 6b425c4dc..0f91b033b 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -510,7 +510,7 @@ bool cWSSAnvil::LoadHeightMapFromNBT(cChunkDef::HeightMap & a_HeightMap, const c
for (int RelX = 0; RelX < cChunkDef::Width; RelX++)
{
const int Index = 4 * (RelX + RelZ * cChunkDef::Width);
- const int Height = GetBEInt(HeightData + Index);
+ const int Height = NetworkBufToHost<Int32>(HeightData + Index);
if (Height > std::numeric_limits<HEIGHTTYPE>::max())
{