summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS2
-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
m---------lib/mbedtls0
-rw-r--r--src/Blocks/BlockAnvil.h2
-rw-r--r--src/Blocks/BlockBed.h2
-rw-r--r--src/Blocks/BlockBigFlower.h7
-rw-r--r--src/Blocks/BlockBrewingStand.h2
-rw-r--r--src/Blocks/BlockButton.h2
-rw-r--r--src/Blocks/BlockCactus.h36
-rw-r--r--src/Blocks/BlockCarpet.h3
-rw-r--r--src/Blocks/BlockChest.h2
-rw-r--r--src/Blocks/BlockCocoaPod.h7
-rw-r--r--src/Blocks/BlockComparator.h43
-rw-r--r--src/Blocks/BlockCrops.h9
-rw-r--r--src/Blocks/BlockDeadBush.h5
-rw-r--r--src/Blocks/BlockDoor.h22
-rw-r--r--src/Blocks/BlockDropSpenser.h2
-rw-r--r--src/Blocks/BlockEnderChest.h2
-rw-r--r--src/Blocks/BlockFenceGate.h2
-rw-r--r--src/Blocks/BlockFlower.h14
-rw-r--r--src/Blocks/BlockFurnace.h2
-rw-r--r--src/Blocks/BlockGlazedTerracotta.h2
-rw-r--r--src/Blocks/BlockHandler.cpp7
-rw-r--r--src/Blocks/BlockHopper.h2
-rw-r--r--src/Blocks/BlockJukebox.h2
-rw-r--r--src/Blocks/BlockLadder.h2
-rw-r--r--src/Blocks/BlockLever.h2
-rw-r--r--src/Blocks/BlockMushroom.h5
-rw-r--r--src/Blocks/BlockNetherWart.h3
-rw-r--r--src/Blocks/BlockObserver.h2
-rw-r--r--src/Blocks/BlockPiston.cpp59
-rw-r--r--src/Blocks/BlockPiston.h2
-rw-r--r--src/Blocks/BlockPortal.h4
-rw-r--r--src/Blocks/BlockPressurePlate.h5
-rw-r--r--src/Blocks/BlockPumpkin.h2
-rw-r--r--src/Blocks/BlockRail.h28
-rw-r--r--src/Blocks/BlockRedstoneRepeater.h44
-rw-r--r--src/Blocks/BlockRedstoneWire.h43
-rw-r--r--src/Blocks/BlockSapling.h14
-rw-r--r--src/Blocks/BlockSignPost.h5
-rw-r--r--src/Blocks/BlockSnow.h4
-rw-r--r--src/Blocks/BlockStairs.h2
-rw-r--r--src/Blocks/BlockStandingBanner.h (renamed from src/Blocks/BlockBanner.h)23
-rw-r--r--src/Blocks/BlockStems.h3
-rw-r--r--src/Blocks/BlockSugarCane.h44
-rw-r--r--src/Blocks/BlockTallGrass.h25
-rw-r--r--src/Blocks/BlockTorch.h4
-rw-r--r--src/Blocks/BlockTrapdoor.h2
-rw-r--r--src/Blocks/BlockTripwireHook.h2
-rw-r--r--src/Blocks/BlockVines.h7
-rw-r--r--src/Blocks/BlockWallBanner.h64
-rw-r--r--src/Blocks/CMakeLists.txt5
-rw-r--r--src/Blocks/Mixins/DirtLikeUnderneath.h42
-rw-r--r--src/Blocks/Mixins/Mixins.h (renamed from src/Blocks/Mixins.h)2
-rw-r--r--src/Blocks/Mixins/SolidSurfaceUnderneath.h65
-rw-r--r--src/ByteBuffer.cpp78
-rw-r--r--src/ChunkMap.cpp22
-rw-r--r--src/ChunkMap.h4
-rw-r--r--src/ClientHandle.cpp11
-rw-r--r--src/Endianness.h183
-rw-r--r--src/Entities/Player.cpp14
-rw-r--r--src/Generating/CompoGenBiomal.cpp5
-rw-r--r--src/Items/ItemBed.h5
-rw-r--r--src/Items/ItemBigFlower.h5
-rw-r--r--src/Items/ItemDoor.h5
-rw-r--r--src/Items/ItemDye.h6
-rw-r--r--src/Items/ItemEyeOfEnder.h4
-rw-r--r--src/Items/ItemHoe.h5
-rw-r--r--src/Items/ItemShears.h5
-rw-r--r--src/Map.cpp10
-rw-r--r--src/Map.h3
-rw-r--r--src/MapManager.cpp37
-rw-r--r--src/MapManager.h4
-rw-r--r--src/Noise/InterpolNoise.h27
-rw-r--r--src/Noise/Noise.cpp45
-rw-r--r--src/Protocol/ChunkDataSerializer.cpp2
-rw-r--r--src/StringUtils.cpp59
-rw-r--r--src/StringUtils.h14
-rw-r--r--src/UI/SlotArea.cpp7
-rw-r--r--src/Vector3.h9
-rw-r--r--src/World.cpp34
-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
-rw-r--r--src/mbedTLS++/CryptoKey.cpp9
-rw-r--r--src/mbedTLS++/RsaPrivateKey.cpp6
-rw-r--r--tests/CompositeChat/CompositeChatTest.cpp1
-rw-r--r--tests/HTTP/UrlClientTest.cpp56
96 files changed, 1122 insertions, 625 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index db229a6f9..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
@@ -80,6 +81,7 @@ Schwertspize
Seadragon91 (Lukas Pioch)
sleirsgoevy (Sergey Lisov)
Sofapriester
+solvictor
Spekdrum (Pablo Beltran)
SphinxC0re
Spongecade (Updated wiki links)
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/lib/mbedtls b/lib/mbedtls
-Subproject f3a2ed06abd98c99db6dc46c9eb400951186d9d
+Subproject 5962c69b26dbfa1e5582a248c0774a8df7ef18f
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h
index bc031216a..eb8053af1 100644
--- a/src/Blocks/BlockAnvil.h
+++ b/src/Blocks/BlockAnvil.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "../Entities/Player.h"
#include "../UI/AnvilWindow.h"
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index a6b2814b9..fcf7d58a0 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -6,7 +6,7 @@
#include "BlockEntity.h"
#include "ChunkInterface.h"
#include "Entities/Player.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h
index 1b2c0d735..d8270dc6c 100644
--- a/src/Blocks/BlockBigFlower.h
+++ b/src/Blocks/BlockBigFlower.h
@@ -25,9 +25,10 @@ private:
if (IsMetaTopPart(a_Meta))
{
BLOCKTYPE BottomType;
+ const auto BottomPosition = a_Position.addedY(-1);
if (
- (a_Position.y < 1) ||
- !a_World.GetBlockTypeMeta(a_Position - Vector3i(0, 1, 0), BottomType, a_Meta) ||
+ !cChunkDef::IsValidHeight(BottomPosition) ||
+ !a_World.GetBlockTypeMeta(BottomPosition, BottomType, a_Meta) ||
(BottomType != E_BLOCK_BIG_FLOWER)
)
{
@@ -104,7 +105,7 @@ private:
// Both parts can only that they're rooted in grass.
const auto RootPosition = a_Position.addedY(IsMetaTopPart(a_Meta) ? -2 : -1);
- return (RootPosition.y >= 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(RootPosition));
+ return cChunkDef::IsValidHeight(RootPosition) && IsBlockTypeOfDirt(a_Chunk.GetBlock(RootPosition));
}
diff --git a/src/Blocks/BlockBrewingStand.h b/src/Blocks/BlockBrewingStand.h
index d1595c690..5f41525d7 100644
--- a/src/Blocks/BlockBrewingStand.h
+++ b/src/Blocks/BlockBrewingStand.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h
index 1a141eff3..e8affb290 100644
--- a/src/Blocks/BlockButton.h
+++ b/src/Blocks/BlockButton.h
@@ -7,7 +7,7 @@
#include "../Chunk.h"
#include "Defines.h"
#include "Entities/Player.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "ChunkInterface.h"
#include "World.h"
diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h
index 23c4d3421..9b1461cb8 100644
--- a/src/Blocks/BlockCactus.h
+++ b/src/Blocks/BlockCactus.h
@@ -20,11 +20,12 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto SurfacePosition = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(SurfacePosition))
{
return false;
}
- BLOCKTYPE Surface = a_Chunk.GetBlock(a_Position.addedY(-1));
+ BLOCKTYPE Surface = a_Chunk.GetBlock(SurfacePosition);
if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS))
{
// Cactus can only be placed on sand and itself
@@ -75,25 +76,25 @@ private:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{
// Check the total height of the cacti blocks here:
- int top = a_RelPos.y + 1;
+ auto Top = a_RelPos.addedY(1);
while (
- (top < cChunkDef::Height) &&
- (a_Chunk.GetBlock({a_RelPos.x, top, a_RelPos.z}) == E_BLOCK_CACTUS)
+ cChunkDef::IsValidHeight(Top) &&
+ (a_Chunk.GetBlock(Top) == E_BLOCK_CACTUS)
)
{
- ++top;
+ Top.y++;
}
- int bottom = a_RelPos.y - 1;
+ auto Bottom = a_RelPos.addedY(-1);
while (
- (bottom > 0) &&
- (a_Chunk.GetBlock({a_RelPos.x, bottom, a_RelPos.z}) == E_BLOCK_CACTUS)
+ cChunkDef::IsValidHeight(Bottom) &&
+ (a_Chunk.GetBlock(Bottom) == E_BLOCK_CACTUS)
)
{
- --bottom;
+ --Bottom.y;
}
// Refuse if already too high:
- auto numToGrow = std::min(a_NumStages, a_Chunk.GetWorld()->GetMaxCactusHeight() + 1 - (top - bottom));
+ auto numToGrow = std::min(a_NumStages, a_Chunk.GetWorld()->GetMaxCactusHeight() + 1 - (Top.y - Bottom.y));
if (numToGrow <= 0)
{
return 0;
@@ -102,14 +103,14 @@ private:
BLOCKTYPE blockType;
for (int i = 0; i < numToGrow; ++i)
{
- Vector3i pos(a_RelPos.x, top + i, a_RelPos.z);
- if (!a_Chunk.UnboundedRelGetBlockType(pos, blockType) || (blockType != E_BLOCK_AIR))
+ auto NewTop = Top.addedY(i);
+ if (!a_Chunk.UnboundedRelGetBlockType(NewTop, blockType) || (blockType != E_BLOCK_AIR))
{
// Cannot grow there
return i;
}
- a_Chunk.UnboundedRelFastSetBlock(pos, E_BLOCK_CACTUS, 0);
+ a_Chunk.UnboundedRelFastSetBlock(NewTop, E_BLOCK_CACTUS, 0);
// Check surroundings. Cacti may ONLY be surrounded by non-solid blocks; if they aren't, drop as pickup and bail out the growing
static const Vector3i neighborOffsets[] =
@@ -122,7 +123,7 @@ private:
for (const auto & ofs: neighborOffsets)
{
if (
- a_Chunk.UnboundedRelGetBlockType(pos + ofs, blockType) &&
+ a_Chunk.UnboundedRelGetBlockType(NewTop + ofs, blockType) &&
(
cBlockInfo::IsSolid(blockType) ||
(blockType == E_BLOCK_LAVA) ||
@@ -131,7 +132,7 @@ private:
)
{
// Remove the cactus
- auto absPos = a_Chunk.RelativeToAbsolute(pos);
+ auto absPos = a_Chunk.RelativeToAbsolute(NewTop);
a_Chunk.GetWorld()->DropBlockAsPickups(absPos);
return i + 1;
}
@@ -143,7 +144,8 @@ private:
virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const override
{
// Only allow growing if there's an air block above:
- if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR))
+ const auto RelPosAbove = a_RelPos.addedY(1);
+ if (cChunkDef::IsValidHeight(RelPosAbove) && (a_Chunk.GetBlock(RelPosAbove) == E_BLOCK_AIR))
{
return Super::CanGrow(a_Chunk, a_RelPos);
}
diff --git a/src/Blocks/BlockCarpet.h b/src/Blocks/BlockCarpet.h
index 841e94b11..2477ee344 100644
--- a/src/Blocks/BlockCarpet.h
+++ b/src/Blocks/BlockCarpet.h
@@ -27,7 +27,8 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- return (a_Position.y > 0) && (a_Chunk.GetBlock(a_Position.addedY(-1)) != E_BLOCK_AIR);
+ const auto PosBelow = a_Position.addedY(-1);
+ return cChunkDef::IsValidHeight(PosBelow) && (a_Chunk.GetBlock(PosBelow) != E_BLOCK_AIR);
}
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index 119216d00..99a95e692 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -3,7 +3,7 @@
#include "../BlockArea.h"
#include "../Entities/Player.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockCocoaPod.h b/src/Blocks/BlockCocoaPod.h
index e018388c5..7906a1888 100644
--- a/src/Blocks/BlockCocoaPod.h
+++ b/src/Blocks/BlockCocoaPod.h
@@ -43,7 +43,12 @@ private:
auto LogPos = AddFaceDirection(a_Position, BlockFace, true);
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- a_Chunk.UnboundedRelGetBlock(LogPos, BlockType, BlockMeta);
+ if (!a_Chunk.UnboundedRelGetBlock(LogPos, BlockType, BlockMeta))
+ {
+ // Don't pop if chunk not loaded.
+ return true;
+ }
+
return ((BlockType == E_BLOCK_LOG) && ((BlockMeta & 0x03) == E_META_LOG_JUNGLE));
}
diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h
index 18aa2a8b9..9ce9d3dbd 100644
--- a/src/Blocks/BlockComparator.h
+++ b/src/Blocks/BlockComparator.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockHandler.h"
-#include "BlockRedstoneRepeater.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
+#include "Mixins/SolidSurfaceUnderneath.h"
class cBlockComparatorHandler final :
- public cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>
+ public cSolidSurfaceUnderneath<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>
{
- using Super = cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>;
+ using Super = cSolidSurfaceUnderneath<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>;
public:
@@ -152,41 +152,6 @@ private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- if (a_Position.y <= 0)
- {
- return false;
- }
-
- BLOCKTYPE BelowBlock;
- NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_Position.addedY(-1), BelowBlock, BelowBlockMeta);
-
- if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
- {
- return true;
- }
-
- // upside down slabs
- if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
- {
- return BelowBlockMeta & E_META_WOODEN_SLAB_UPSIDE_DOWN;
- }
-
- // upside down stairs
- if (cBlockStairsHandler::IsAnyStairType(BelowBlock))
- {
- return BelowBlockMeta & E_BLOCK_STAIRS_UPSIDE_DOWN;
- }
-
- return false;
- }
-
-
-
-
-
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
{
return cItem(E_ITEM_COMPARATOR, 1, 0);
diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h
index b323ace10..59413ba08 100644
--- a/src/Blocks/BlockCrops.h
+++ b/src/Blocks/BlockCrops.h
@@ -118,7 +118,14 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- return (a_Position.y > 0) && (a_Chunk.GetBlock(a_Position.addedY(-1)) == E_BLOCK_FARMLAND);
+ const auto BlockBelow = a_Position.addedY(-1);
+
+ if (!cChunkDef::IsValidHeight(BlockBelow))
+ {
+ return false;
+ }
+
+ return a_Chunk.GetBlock(BlockBelow) == E_BLOCK_FARMLAND;
}
diff --git a/src/Blocks/BlockDeadBush.h b/src/Blocks/BlockDeadBush.h
index 080dd150c..884b6f686 100644
--- a/src/Blocks/BlockDeadBush.h
+++ b/src/Blocks/BlockDeadBush.h
@@ -29,12 +29,13 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto PosBelow = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(PosBelow))
{
return false;
}
- BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_Position.addedY(-1));
+ BLOCKTYPE BelowBlock = a_Chunk.GetBlock(PosBelow);
switch (BelowBlock)
{
case E_BLOCK_CLAY:
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 1b5c33d46..c394bda39 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -5,7 +5,7 @@
#include "../BlockInfo.h"
#include "../Entities/Player.h"
#include "../Chunk.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "ChunkInterface.h"
#include "BlockSlab.h"
@@ -191,14 +191,18 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
// CanBeAt is also called on placement, so the top part can't check for the bottom part.
- // Both parts can only that their base is a valid block.
+ // Both parts can only check that the base of the door (i.e. -2 for a door top) is a valid block.
+ const auto BasePosition = a_Position.addedY(((a_Meta & 0x8) == 0x8) ? -2 : -1);
+ if (!cChunkDef::IsValidHeight(BasePosition))
+ {
+ return false;
+ }
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- const auto BasePosition = a_Position.addedY(((a_Meta & 0x8) == 0x8) ? -2 : -1);
a_Chunk.GetBlockTypeMeta(BasePosition, BlockType, BlockMeta);
- return (BasePosition.y >= 0) && CanBeOn(BlockType, BlockMeta);
+ return CanBeOn(BlockType, BlockMeta);
}
@@ -216,9 +220,10 @@ private:
if ((Meta & 0x08) != 0)
{
// The coords are pointing at the top part of the door
- if (a_BlockPos.y > 0)
+ const auto BottomPos = a_BlockPos.addedY(-1);
+ if (cChunkDef::IsValidHeight(BottomPos))
{
- NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockPos.addedY(-1));
+ NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(BottomPos);
return static_cast<NIBBLETYPE>((DownMeta & 0x07) | 0x08 | (Meta << 4));
}
// This is the top part of the door at the bottommost layer of the world, there's no bottom:
@@ -227,9 +232,10 @@ private:
else
{
// The coords are pointing at the bottom part of the door
- if (a_BlockPos.y < cChunkDef::Height - 1)
+ const auto TopPos = a_BlockPos.addedY(1);
+ if (cChunkDef::IsValidHeight(TopPos))
{
- NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockPos.addedY(1));
+ NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(TopPos);
return static_cast<NIBBLETYPE>(Meta | (UpMeta << 4));
}
// This is the bottom part of the door at the topmost layer of the world, there's no top:
diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h
index 050adf0f1..7b18eb8da 100644
--- a/src/Blocks/BlockDropSpenser.h
+++ b/src/Blocks/BlockDropSpenser.h
@@ -5,7 +5,7 @@
#pragma once
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockEnderChest.h b/src/Blocks/BlockEnderChest.h
index 2e0da0f17..a944ab263 100644
--- a/src/Blocks/BlockEnderChest.h
+++ b/src/Blocks/BlockEnderChest.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h
index f52d8df9c..75a0ded06 100644
--- a/src/Blocks/BlockFenceGate.h
+++ b/src/Blocks/BlockFenceGate.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "../EffectID.h"
diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h
index 023ba4a37..aaa532c0c 100644
--- a/src/Blocks/BlockFlower.h
+++ b/src/Blocks/BlockFlower.h
@@ -2,15 +2,16 @@
#pragma once
#include "BlockHandler.h"
+#include "Mixins/DirtLikeUnderneath.h"
class cBlockFlowerHandler final :
- public cBlockHandler
+ public cDirtLikeUnderneath<cBlockHandler>
{
- using Super = cBlockHandler;
+ using Super = cDirtLikeUnderneath<cBlockHandler>;
public:
@@ -28,15 +29,6 @@ private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- return (a_Position.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_Position.addedY(-1)));
- }
-
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h
index 8cdc9489a..968ea398c 100644
--- a/src/Blocks/BlockFurnace.h
+++ b/src/Blocks/BlockFurnace.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockGlazedTerracotta.h b/src/Blocks/BlockGlazedTerracotta.h
index 0975f1ecd..21206ab77 100644
--- a/src/Blocks/BlockGlazedTerracotta.h
+++ b/src/Blocks/BlockGlazedTerracotta.h
@@ -1,7 +1,7 @@
#pragma once
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 4b0d7e5ec..6691f151f 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -7,7 +7,6 @@
#include "BlockPluginInterface.h"
#include "BlockAir.h"
#include "BlockAnvil.h"
-#include "BlockBanner.h"
#include "BlockBed.h"
#include "BlockBigFlower.h"
#include "BlockBookShelf.h"
@@ -89,6 +88,7 @@
#include "BlockSnow.h"
#include "BlockSponge.h"
#include "BlockStairs.h"
+#include "BlockStandingBanner.h"
#include "BlockStems.h"
#include "BlockStone.h"
#include "BlockSugarCane.h"
@@ -99,6 +99,7 @@
#include "BlockTripwire.h"
#include "BlockTripwireHook.h"
#include "BlockVines.h"
+#include "BlockWallBanner.h"
#include "BlockWallSign.h"
#include "BlockWorkbench.h"
@@ -413,7 +414,7 @@ namespace
constexpr cDefaultBlockHandler BlockStainedClayHandler (E_BLOCK_STAINED_CLAY);
constexpr cBlockGlassHandler BlockStainedGlassHandler (E_BLOCK_STAINED_GLASS);
constexpr cBlockGlassHandler BlockStainedGlassPaneHandler (E_BLOCK_STAINED_GLASS_PANE);
- constexpr cBlockBannerHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER);
+ constexpr cBlockStandingBannerHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER);
constexpr cBlockLavaHandler BlockStationaryLavaHandler (E_BLOCK_STATIONARY_LAVA);
constexpr cBlockWaterHandler BlockStationaryWaterHandler (E_BLOCK_STATIONARY_WATER);
constexpr cBlockPistonHandler BlockStickyPistonHandler (E_BLOCK_STICKY_PISTON);
@@ -434,7 +435,7 @@ namespace
constexpr cBlockTripwireHandler BlockTripwireHandler (E_BLOCK_TRIPWIRE);
constexpr cBlockTripwireHookHandler BlockTripwireHookHandler (E_BLOCK_TRIPWIRE_HOOK);
constexpr cBlockVinesHandler BlockVinesHandler (E_BLOCK_VINES);
- constexpr cBlockBannerHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER);
+ constexpr cBlockWallBannerHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER);
constexpr cBlockWallSignHandler BlockWallsignHandler (E_BLOCK_WALLSIGN);
constexpr cBlockWaterHandler BlockWaterHandler (E_BLOCK_WATER);
constexpr cBlockGlazedTerracottaHandler BlockWhiteGlazedTerracottaHandler (E_BLOCK_WHITE_GLAZED_TERRACOTTA);
diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h
index 930f1e0bc..91ad91bff 100644
--- a/src/Blocks/BlockHopper.h
+++ b/src/Blocks/BlockHopper.h
@@ -3,7 +3,7 @@
// Declares the cBlockHopperHandler class representing the handler for the Hopper block
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockJukebox.h b/src/Blocks/BlockJukebox.h
index 970f10fc1..79475d30b 100644
--- a/src/Blocks/BlockJukebox.h
+++ b/src/Blocks/BlockJukebox.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockEntity.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h
index bab51b2d3..4bca19930 100644
--- a/src/Blocks/BlockLadder.h
+++ b/src/Blocks/BlockLadder.h
@@ -3,7 +3,7 @@
#include "BlockHandler.h"
#include "BlockInfo.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h
index 60db4ddee..2a676ce00 100644
--- a/src/Blocks/BlockLever.h
+++ b/src/Blocks/BlockLever.h
@@ -5,7 +5,7 @@
#include "Blocks/BlockStairs.h"
#include "ChunkDef.h"
#include "Defines.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "BlockSlab.h"
diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h
index bed16c557..9e4378d4e 100644
--- a/src/Blocks/BlockMushroom.h
+++ b/src/Blocks/BlockMushroom.h
@@ -23,14 +23,15 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto BasePos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BasePos))
{
return false;
}
// TODO: Cannot be at too much daylight
- switch (a_Chunk.GetBlock(a_Position.addedY(-1)))
+ switch (a_Chunk.GetBlock(BasePos))
{
case E_BLOCK_GLASS:
case E_BLOCK_CACTUS:
diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h
index 43081d511..c0686afc6 100644
--- a/src/Blocks/BlockNetherWart.h
+++ b/src/Blocks/BlockNetherWart.h
@@ -60,7 +60,8 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
// Needs to be placed on top of a Soulsand block:
- return (a_Position.y > 0) && (a_Chunk.GetBlock(a_Position.addedY(-1)) == E_BLOCK_SOULSAND);
+ const auto BasePos = a_Position.addedY(-1);
+ return cChunkDef::IsValidHeight(BasePos) && (a_Chunk.GetBlock(BasePos) == E_BLOCK_SOULSAND);
}
diff --git a/src/Blocks/BlockObserver.h b/src/Blocks/BlockObserver.h
index 13ffa4631..c2cab3068 100644
--- a/src/Blocks/BlockObserver.h
+++ b/src/Blocks/BlockObserver.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
class cBlockObserverHandler final :
diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp
index 124757b44..568e2eaa5 100644
--- a/src/Blocks/BlockPiston.cpp
+++ b/src/Blocks/BlockPiston.cpp
@@ -48,8 +48,12 @@ void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World)
BLOCKTYPE pistonBlock;
NIBBLETYPE pistonMeta;
- a_World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
- a_World.BroadcastBlockAction(a_BlockPos, PistonExtendAction, pistonMeta, pistonBlock);
+ if (a_World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta))
+ {
+ a_World.BroadcastBlockAction(
+ a_BlockPos, PistonExtendAction, pistonMeta, pistonBlock
+ );
+ }
}
// Client expects the server to "play" the animation before setting the final blocks
@@ -60,9 +64,12 @@ void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld & a_World)
{
BLOCKTYPE pistonBlock;
NIBBLETYPE pistonMeta;
- World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
- if ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+
+ if (
+ !World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta) ||
+ ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+ )
{
// Ensure we operate on a piston to avoid spurious behaviour
// Note that the scheduled task may result in the block type of a_BlockPos changing
@@ -104,17 +111,23 @@ void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld & a_World)
{
BLOCKTYPE pistonBlock;
NIBBLETYPE pistonMeta;
- a_World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
- a_World.BroadcastBlockAction(a_BlockPos, PistonRetractAction, pistonMeta, pistonBlock);
+ if (a_World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta))
+ {
+ a_World.BroadcastBlockAction(
+ a_BlockPos, PistonRetractAction, pistonMeta, pistonBlock
+ );
+ }
}
a_World.ScheduleTask(1_tick, [a_BlockPos](cWorld & World)
{
BLOCKTYPE pistonBlock;
NIBBLETYPE pistonMeta;
- World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta);
- if ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+ if (
+ !World.GetBlockTypeMeta(a_BlockPos, pistonBlock, pistonMeta) ||
+ ((pistonBlock != E_BLOCK_PISTON) && !IsSticky(pistonBlock))
+ )
{
// Ensure we operate on a piston to avoid spurious behaviour
// Note that the scheduled task may result in the block type of a_BlockPos changing
@@ -189,19 +202,20 @@ void cBlockPistonHandler::PushBlocks(
NIBBLETYPE moveMeta;
for (auto & moveBlockPos : sortedBlocks)
{
- a_World.GetBlockTypeMeta(moveBlockPos, moveBlock, moveMeta);
-
- if (cBlockInfo::IsPistonBreakable(moveBlock))
- {
- // Block is breakable, drop it:
- a_World.DropBlockAsPickups(moveBlockPos, nullptr, nullptr);
- }
- else
+ if (a_World.GetBlockTypeMeta(moveBlockPos, moveBlock, moveMeta))
{
- // Not breakable, just move it
- a_World.SetBlock(moveBlockPos, E_BLOCK_AIR, 0);
- moveBlockPos += a_PushDir;
- a_World.SetBlock(moveBlockPos, moveBlock, moveMeta);
+ if (cBlockInfo::IsPistonBreakable(moveBlock))
+ {
+ // Block is breakable, drop it:
+ a_World.DropBlockAsPickups(moveBlockPos, nullptr, nullptr);
+ }
+ else
+ {
+ // Not breakable, just move it
+ a_World.SetBlock(moveBlockPos, E_BLOCK_AIR, 0);
+ moveBlockPos += a_PushDir;
+ a_World.SetBlock(moveBlockPos, moveBlock, moveMeta);
+ }
}
}
}
@@ -232,7 +246,10 @@ bool cBlockPistonHandler::CanPushBlock(
BLOCKTYPE currBlock;
NIBBLETYPE currMeta;
- a_World.GetBlockTypeMeta(a_BlockPos, currBlock, currMeta);
+ if (!a_World.GetBlockTypeMeta(a_BlockPos, currBlock, currMeta))
+ {
+ return !a_RequirePushable;
+ }
if (currBlock == E_BLOCK_AIR)
{
diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h
index 4afeb4767..275214036 100644
--- a/src/Blocks/BlockPiston.h
+++ b/src/Blocks/BlockPiston.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "../Item.h"
diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h
index 05daa9337..f4b5a50bd 100644
--- a/src/Blocks/BlockPortal.h
+++ b/src/Blocks/BlockPortal.h
@@ -51,9 +51,9 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if ((a_Position.y <= 0) || (a_Position.y >= cChunkDef::Height - 1))
+ if (!cChunkDef::IsValidHeight(a_Position.addedY(-1)) || !cChunkDef::IsValidHeight(a_Position.addedY(1)))
{
- return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1.
+ return false; // Must be 1 away from the boundary, there will always be another portal or an obsidian between the portal block and the boundary.
}
switch (a_Meta)
diff --git a/src/Blocks/BlockPressurePlate.h b/src/Blocks/BlockPressurePlate.h
index 6d852bfc0..d69234cee 100644
--- a/src/Blocks/BlockPressurePlate.h
+++ b/src/Blocks/BlockPressurePlate.h
@@ -22,14 +22,15 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto PosBelow = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(PosBelow))
{
return false;
}
BLOCKTYPE Block;
NIBBLETYPE BlockMeta;
- a_Chunk.GetBlockTypeMeta(a_Position.addedY(-1), Block, BlockMeta);
+ a_Chunk.GetBlockTypeMeta(PosBelow, Block, BlockMeta);
// upside down slabs
if (cBlockSlabHandler::IsAnySlabType(Block))
diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h
index e627eeaee..fa73db56a 100644
--- a/src/Blocks/BlockPumpkin.h
+++ b/src/Blocks/BlockPumpkin.h
@@ -1,7 +1,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h
index 4e2e6211f..dea84296f 100644
--- a/src/Blocks/BlockRail.h
+++ b/src/Blocks/BlockRail.h
@@ -1,10 +1,9 @@
#pragma once
#include "BlockHandler.h"
-#include "BlockSlab.h"
-#include "BlockStairs.h"
#include "BlockType.h"
-#include "Blocks/Mixins.h"
+#include "Mixins/Mixins.h"
+#include "Mixins/SolidSurfaceUnderneath.h"
#include "../BlockInfo.h"
#include "../Chunk.h"
#include "ChunkDef.h"
@@ -25,9 +24,9 @@ enum ENUM_PURE
class cBlockRailHandler final :
- public cClearMetaOnDrop<cBlockHandler>
+ public cSolidSurfaceUnderneath<cClearMetaOnDrop<cBlockHandler>>
{
- using Super = cClearMetaOnDrop<cBlockHandler>;
+ using Super = cSolidSurfaceUnderneath<cClearMetaOnDrop<cBlockHandler>>;
public:
@@ -162,26 +161,9 @@ public:
private:
- static bool CanBeSupportedBy(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
- {
- if (cBlockSlabHandler::IsAnySlabType(a_BlockType))
- {
- return (a_BlockMeta & E_META_WOODEN_SLAB_UPSIDE_DOWN);
- }
- else if (cBlockStairsHandler::IsAnyStairType(a_BlockType))
- {
- return (a_BlockMeta & E_BLOCK_STAIRS_UPSIDE_DOWN);
- }
- return cBlockInfo::FullyOccupiesVoxel(a_BlockType);
- }
-
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, NIBBLETYPE a_Meta) const override
{
- BLOCKTYPE BelowBlock;
- NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_Position.addedY(-1), BelowBlock, BelowBlockMeta);
-
- if ((a_Position.y <= 0) || !CanBeSupportedBy(BelowBlock, BelowBlockMeta))
+ if (!Super::CanBeAt(a_Chunk, a_Position, a_Meta))
{
return false;
}
diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h
index 893691d7b..92b4b3917 100644
--- a/src/Blocks/BlockRedstoneRepeater.h
+++ b/src/Blocks/BlockRedstoneRepeater.h
@@ -3,10 +3,9 @@
#include "BlockHandler.h"
#include "BlockType.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
+#include "Mixins/SolidSurfaceUnderneath.h"
#include "ChunkInterface.h"
-#include "BlockSlab.h"
-#include "BlockStairs.h"
#include "../Chunk.h"
@@ -14,9 +13,9 @@
class cBlockRedstoneRepeaterHandler final :
- public cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>
+ public cSolidSurfaceUnderneath<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>
{
- using Super = cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>;
+ using Super = cSolidSurfaceUnderneath<cYawRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03>>;
public:
@@ -107,41 +106,6 @@ private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- if (a_Position.y <= 0)
- {
- return false;
- }
-
- BLOCKTYPE BelowBlock;
- NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_Position.addedY(-1), BelowBlock, BelowBlockMeta);
-
- if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
- {
- return true;
- }
-
- // upside down slabs
- if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
- {
- return BelowBlockMeta & E_META_WOODEN_SLAB_UPSIDE_DOWN;
- }
-
- // upside down stairs
- if (cBlockStairsHandler::IsAnyStairType(BelowBlock))
- {
- return BelowBlockMeta & E_BLOCK_STAIRS_UPSIDE_DOWN;
- }
-
- return false;
- }
-
-
-
-
-
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
{
return cItem(E_ITEM_REDSTONE_REPEATER, 1, 0);
diff --git a/src/Blocks/BlockRedstoneWire.h b/src/Blocks/BlockRedstoneWire.h
index de8e59a40..edea704f4 100644
--- a/src/Blocks/BlockRedstoneWire.h
+++ b/src/Blocks/BlockRedstoneWire.h
@@ -2,17 +2,15 @@
#pragma once
#include "BlockHandler.h"
-#include "BlockSlab.h"
-#include "BlockStairs.h"
-#include "../Chunk.h"
+#include "Mixins/SolidSurfaceUnderneath.h"
class cBlockRedstoneWireHandler final :
- public cBlockHandler
+ public cSolidSurfaceUnderneath<cBlockHandler>
{
- using Super = cBlockHandler;
+ using Super = cSolidSurfaceUnderneath<cBlockHandler>;
public:
@@ -20,41 +18,6 @@ public:
private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- if (a_Position.y <= 0)
- {
- return false;
- }
-
- BLOCKTYPE BelowBlock;
- NIBBLETYPE BelowBlockMeta;
- a_Chunk.GetBlockTypeMeta(a_Position.addedY(-1), BelowBlock, BelowBlockMeta);
-
- if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
- {
- return true;
- }
-
- // upside down slabs
- if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
- {
- return BelowBlockMeta & E_META_WOODEN_SLAB_UPSIDE_DOWN;
- }
-
- // upside down stairs
- if (cBlockStairsHandler::IsAnyStairType(BelowBlock))
- {
- return BelowBlockMeta & E_BLOCK_STAIRS_UPSIDE_DOWN;
- }
-
- return false;
- }
-
-
-
-
-
virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
{
return cItem(E_ITEM_REDSTONE_DUST, 1, 0);
diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h
index d32b9b449..db953946a 100644
--- a/src/Blocks/BlockSapling.h
+++ b/src/Blocks/BlockSapling.h
@@ -3,15 +3,16 @@
#include "BlockHandler.h"
#include "../FastRandom.h"
+#include "Mixins/DirtLikeUnderneath.h"
class cBlockSaplingHandler final :
- public cBlockHandler
+ public cDirtLikeUnderneath<cBlockHandler>
{
- using Super = cBlockHandler;
+ using Super = cDirtLikeUnderneath<cBlockHandler>;
public:
@@ -29,15 +30,6 @@ private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- return (a_Position.y > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_Position.addedY(-1)));
- }
-
-
-
-
-
virtual void OnUpdate(
cChunkInterface & a_ChunkInterface,
cWorldInterface & a_WorldInterface,
diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h
index b96498cbd..89da77fbb 100644
--- a/src/Blocks/BlockSignPost.h
+++ b/src/Blocks/BlockSignPost.h
@@ -30,12 +30,13 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto BelowPos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BelowPos))
{
return false;
}
- BLOCKTYPE Type = a_Chunk.GetBlock(a_Position.addedY(-1));
+ BLOCKTYPE Type = a_Chunk.GetBlock(BelowPos);
return (Type == E_BLOCK_SIGN_POST) || (Type == E_BLOCK_WALLSIGN) || cBlockInfo::IsSolid(Type);
}
diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h
index f3fa87a1b..51361ce17 100644
--- a/src/Blocks/BlockSnow.h
+++ b/src/Blocks/BlockSnow.h
@@ -69,11 +69,11 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto BelowPos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BelowPos))
{
return false;
}
- auto BelowPos = a_Position.addedY(-1);
auto BlockBelow = a_Chunk.GetBlock(BelowPos);
auto MetaBelow = a_Chunk.GetMeta(BelowPos);
return CanBeOn(BlockBelow, MetaBelow);
diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h
index 76614bb62..6c37a8464 100644
--- a/src/Blocks/BlockStairs.h
+++ b/src/Blocks/BlockStairs.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockBanner.h b/src/Blocks/BlockStandingBanner.h
index e6a159bd4..0cc7c28eb 100644
--- a/src/Blocks/BlockBanner.h
+++ b/src/Blocks/BlockStandingBanner.h
@@ -1,19 +1,20 @@
-// BlockBanner.h
+// BlockStandingBanner.h
#pragma once
#include "../BlockInfo.h"
#include "BlockEntity.h"
+#include "Mixins/SolidSurfaceUnderneath.h"
-class cBlockBannerHandler final :
- public cBlockEntityHandler
+class cBlockStandingBannerHandler final :
+ public cSolidSurfaceUnderneath<cBlockEntityHandler>
{
- using Super = cBlockEntityHandler;
+ using Super = cSolidSurfaceUnderneath<cBlockEntityHandler>;
public:
@@ -29,20 +30,6 @@ public:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- if (a_Position.y < 1)
- {
- return false;
- }
-
- return cBlockInfo::IsSolid(a_Chunk.GetBlock(a_Position.addedY(-1)));
- }
-
-
-
-
-
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h
index 11cd83967..9d598003d 100644
--- a/src/Blocks/BlockStems.h
+++ b/src/Blocks/BlockStems.h
@@ -58,7 +58,8 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- return (a_Position.y > 0) && (a_Chunk.GetBlock(a_Position.addedY(-1)) == E_BLOCK_FARMLAND);
+ const auto BelowPos = a_Position.addedY(-1);
+ return cChunkDef::IsValidHeight(BelowPos) && (a_Chunk.GetBlock(BelowPos) == E_BLOCK_FARMLAND);
}
diff --git a/src/Blocks/BlockSugarCane.h b/src/Blocks/BlockSugarCane.h
index cffe667e5..1f6c8a8fa 100644
--- a/src/Blocks/BlockSugarCane.h
+++ b/src/Blocks/BlockSugarCane.h
@@ -29,12 +29,13 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
- if (a_Position.y <= 0)
+ const auto BelowPos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BelowPos))
{
return false;
}
- switch (a_Chunk.GetBlock(a_Position.addedY(-1)))
+ switch (a_Chunk.GetBlock(BelowPos))
{
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
@@ -43,16 +44,16 @@ private:
{
static const Vector3i Coords[] =
{
- {-1, -1, 0},
- { 1, -1, 0},
- { 0, -1, -1},
- { 0, -1, 1},
+ {-1, 0, 0},
+ { 1, 0, 0},
+ { 0, 0, -1},
+ { 0, 0, 1},
} ;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- if (!a_Chunk.UnboundedRelGetBlock(a_Position + Coords[i], BlockType, BlockMeta))
+ if (!a_Chunk.UnboundedRelGetBlock(BelowPos + Coords[i], BlockType, BlockMeta))
{
// Too close to the edge, cannot simulate
return true;
@@ -90,31 +91,36 @@ private:
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{
// Check the total height of the sugarcane blocks here:
- int top = a_RelPos.y + 1;
+ auto top = a_RelPos.addedY(1);
while (
- (top < cChunkDef::Height) &&
- (a_Chunk.GetBlock({a_RelPos.x, top, a_RelPos.z}) == E_BLOCK_SUGARCANE)
+ cChunkDef::IsValidHeight(top) &&
+ (a_Chunk.GetBlock(top) == E_BLOCK_SUGARCANE)
)
{
- ++top;
+ ++top.y;
}
- int bottom = a_RelPos.y - 1;
+ auto bottom = a_RelPos.addedY(-1);
while (
- (bottom > 0) &&
- (a_Chunk.GetBlock({a_RelPos.x, bottom, a_RelPos.z}) == E_BLOCK_SUGARCANE)
+ cChunkDef::IsValidHeight(bottom) &&
+ (a_Chunk.GetBlock(bottom) == E_BLOCK_SUGARCANE)
)
{
- --bottom;
+ --bottom.y;
}
// Grow by at most a_NumStages, but no more than max height:
- auto toGrow = std::min(a_NumStages, a_Chunk.GetWorld()->GetMaxSugarcaneHeight() + 1 - (top - bottom));
- Vector3i topPos(a_RelPos.x, top, a_RelPos.z);
+ auto toGrow = std::min(a_NumStages, a_Chunk.GetWorld()->GetMaxSugarcaneHeight() + 1 - (top.y - bottom.y));
for (int i = 0; i < toGrow; i++)
{
- if (a_Chunk.GetBlock(topPos.addedY(i)) == E_BLOCK_AIR)
+ const auto NewTop = top.addedY(i);
+ if (!cChunkDef::IsValidHeight(NewTop))
{
- a_Chunk.SetBlock(topPos.addedY(i), E_BLOCK_SUGARCANE, 0);
+ return i;
+ }
+
+ if (a_Chunk.GetBlock(NewTop) == E_BLOCK_AIR)
+ {
+ a_Chunk.SetBlock(NewTop, E_BLOCK_SUGARCANE, 0);
}
else
{
diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h
index ea638c878..47ad2f93d 100644
--- a/src/Blocks/BlockTallGrass.h
+++ b/src/Blocks/BlockTallGrass.h
@@ -2,6 +2,7 @@
#pragma once
#include "BlockHandler.h"
+#include "Mixins/DirtLikeUnderneath.h"
#include "ChunkInterface.h"
@@ -10,9 +11,9 @@
/** Handles the grass that is 1 block tall */
class cBlockTallGrassHandler final :
- public cBlockHandler
+ public cDirtLikeUnderneath<cBlockHandler>
{
- using Super = cBlockHandler;
+ using Super = cDirtLikeUnderneath<cBlockHandler>;
public:
@@ -52,25 +53,11 @@ private:
- virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
- {
- if (a_Position.y <= 0)
- {
- return false;
- }
-
- BLOCKTYPE BelowBlock = a_Chunk.GetBlock(a_Position.addedY(-1));
- return IsBlockTypeOfDirt(BelowBlock);
- }
-
-
-
-
-
/** Growing a tall grass produces a big flower (2-block high fern or double-tall grass). */
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
{
- if (a_RelPos.y > (cChunkDef::Height - 2))
+ const auto TopPos = a_RelPos.addedY(1);
+ if (!cChunkDef::IsValidHeight(TopPos))
{
return 0;
}
@@ -83,7 +70,7 @@ private:
default: return 0;
}
a_Chunk.SetBlock(a_RelPos, E_BLOCK_BIG_FLOWER, largeFlowerMeta);
- a_Chunk.SetBlock(a_RelPos.addedY(1), E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
+ a_Chunk.SetBlock(TopPos, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
return 1;
}
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index ad69cf5eb..99f685cb6 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -7,7 +7,7 @@
#include "BlockType.h"
#include "ChunkInterface.h"
#include "Defines.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
@@ -126,7 +126,7 @@ private:
NIBBLETYPE NeighborBlockMeta;
if (!a_Chunk.UnboundedRelGetBlock(NeighborRelPos, NeighborBlockType, NeighborBlockMeta))
{
- // Neighbor in an unloaded chunk, bail out without changint this.
+ // Neighbor in an unloaded chunk, bail out without changing this.
return false;
}
diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h
index 7f6f70e1e..3fb4f4ca3 100644
--- a/src/Blocks/BlockTrapdoor.h
+++ b/src/Blocks/BlockTrapdoor.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
#include "../EffectID.h"
diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h
index ae553d66f..ede6ca311 100644
--- a/src/Blocks/BlockTripwireHook.h
+++ b/src/Blocks/BlockTripwireHook.h
@@ -1,7 +1,7 @@
#pragma once
#include "BlockHandler.h"
-#include "Mixins.h"
+#include "Mixins/Mixins.h"
diff --git a/src/Blocks/BlockVines.h b/src/Blocks/BlockVines.h
index a23ba1489..edbd30f36 100644
--- a/src/Blocks/BlockVines.h
+++ b/src/Blocks/BlockVines.h
@@ -119,15 +119,16 @@ private:
}
// Check if vine above us, add its meta to MaxMeta:
- if ((a_Position.y < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_Position.addedY(1)) == E_BLOCK_VINES))
+ const auto AbovePos = a_Position.addedY(1);
+ if (cChunkDef::IsValidHeight(AbovePos) && (a_Chunk.GetBlock(AbovePos) == E_BLOCK_VINES))
{
- MaxMeta |= a_Chunk.GetMeta(a_Position.addedY(1));
+ MaxMeta |= a_Chunk.GetMeta(AbovePos);
}
NIBBLETYPE Common = a_CurrentMeta & MaxMeta; // Neighbors that we have and are legal.
if (Common != a_CurrentMeta)
{
- bool HasTop = (a_Position.y < (cChunkDef::Height - 1)) && IsBlockAttachable(a_Chunk.GetBlock(a_Position.addedY(1)));
+ bool HasTop = cChunkDef::IsValidHeight(AbovePos) && IsBlockAttachable(a_Chunk.GetBlock(AbovePos));
if ((Common == 0) && !HasTop) // Meta equals 0 also means top. Make a last-ditch attempt to save the vine.
{
return VINE_LOST_SUPPORT;
diff --git a/src/Blocks/BlockWallBanner.h b/src/Blocks/BlockWallBanner.h
new file mode 100644
index 000000000..e0ebb8eee
--- /dev/null
+++ b/src/Blocks/BlockWallBanner.h
@@ -0,0 +1,64 @@
+
+// BlockWallBanner.h
+
+#pragma once
+
+#include "../BlockInfo.h"
+#include "BlockEntity.h"
+
+
+
+
+
+class cBlockWallBannerHandler final :
+ public cBlockEntityHandler
+{
+ using Super = cBlockEntityHandler;
+
+public:
+
+ using Super::Super;
+
+ virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
+ {
+ // Drops handled by the block entity:
+ return {};
+ }
+
+
+
+
+
+ virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
+ {
+ Vector3i Offset;
+
+ switch (a_Meta)
+ {
+ case BLOCK_FACE_ZM: Offset = Vector3i( 0, 0, 1); break;
+ case BLOCK_FACE_ZP: Offset = Vector3i( 0, 0, -1); break;
+ case BLOCK_FACE_XM: Offset = Vector3i( 1, 0, 0); break;
+ case BLOCK_FACE_XP: Offset = Vector3i(-1, 0, 0); break;
+ default: return false;
+ }
+
+ auto NeighborPos = a_Position + Offset;
+ BLOCKTYPE NeighborType;
+ if (!a_Chunk.UnboundedRelGetBlockType(NeighborPos, NeighborType))
+ {
+ // The neighbour is not accessible (unloaded chunk), we'll allow it for now.
+ return true;
+ }
+ return cBlockInfo::IsSolid(NeighborType);
+ }
+
+
+
+
+
+ virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
+ {
+ UNUSED(a_Meta);
+ return 0;
+ }
+} ;
diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt
index a7dd7b675..7e3047451 100644
--- a/src/Blocks/CMakeLists.txt
+++ b/src/Blocks/CMakeLists.txt
@@ -9,7 +9,6 @@ target_sources(
BlockAir.h
BlockAnvil.h
- BlockBanner.h
BlockBed.h
BlockBigFlower.h
BlockBookShelf.h
@@ -94,6 +93,7 @@ target_sources(
BlockSnow.h
BlockSponge.h
BlockStairs.h
+ BlockStandingBanner.h
BlockStems.h
BlockStone.h
BlockSugarCane.h
@@ -104,11 +104,12 @@ target_sources(
BlockTripwire.h
BlockTripwireHook.h
BlockVines.h
+ BlockWallBanner.h
BlockWallSign.h
BlockWorkbench.h
BroadcastInterface.h
ChunkInterface.h
GetHandlerCompileTimeTemplate.h
- Mixins.h
+ Mixins/Mixins.h
WorldInterface.h
)
diff --git a/src/Blocks/Mixins/DirtLikeUnderneath.h b/src/Blocks/Mixins/DirtLikeUnderneath.h
new file mode 100644
index 000000000..909f1601e
--- /dev/null
+++ b/src/Blocks/Mixins/DirtLikeUnderneath.h
@@ -0,0 +1,42 @@
+
+#pragma once
+
+#include "../../Chunk.h"
+
+/** Mixin to ensure the block has a dirt-like block underneath. */
+template <class Base>
+class cDirtLikeUnderneath :
+ public Base
+{
+ using Super = Base;
+public:
+
+ using Super::Super;
+
+ constexpr cDirtLikeUnderneath(BLOCKTYPE a_BlockType):
+ Base(a_BlockType)
+ {
+ }
+
+protected:
+
+ ~cDirtLikeUnderneath() = default;
+
+protected:
+
+ virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
+ {
+ if (!Super::CanBeAt(a_Chunk, a_Position, a_Meta))
+ {
+ return false;
+ }
+
+ const auto BelowPos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BelowPos))
+ {
+ return false;
+ }
+
+ return IsBlockTypeOfDirt(a_Chunk.GetBlock(BelowPos));
+ }
+};
diff --git a/src/Blocks/Mixins.h b/src/Blocks/Mixins/Mixins.h
index fa8985737..d9a233bad 100644
--- a/src/Blocks/Mixins.h
+++ b/src/Blocks/Mixins/Mixins.h
@@ -9,7 +9,7 @@ class cBlockLadder: public cMetaRotator<cClearMetaOnDrop, ...>
#pragma once
-#include "../Item.h"
+#include "../../Item.h"
diff --git a/src/Blocks/Mixins/SolidSurfaceUnderneath.h b/src/Blocks/Mixins/SolidSurfaceUnderneath.h
new file mode 100644
index 000000000..c54c064d6
--- /dev/null
+++ b/src/Blocks/Mixins/SolidSurfaceUnderneath.h
@@ -0,0 +1,65 @@
+
+#pragma once
+
+#include "../../Chunk.h"
+#include "../BlockSlab.h"
+#include "../BlockStairs.h"
+
+/** Mixin to ensure the block has a solid surface underneath. */
+template <class Base>
+class cSolidSurfaceUnderneath :
+ public Base
+{
+ using Super = Base;
+public:
+
+ using Super::Super;
+
+ constexpr cSolidSurfaceUnderneath(BLOCKTYPE a_BlockType):
+ Base(a_BlockType)
+ {
+ }
+
+protected:
+
+ ~cSolidSurfaceUnderneath() = default;
+
+protected:
+
+ virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
+ {
+ if (!Super::CanBeAt(a_Chunk, a_Position, a_Meta))
+ {
+ return false;
+ }
+
+ const auto BelowPos = a_Position.addedY(-1);
+ if (!cChunkDef::IsValidHeight(BelowPos))
+ {
+ return false;
+ }
+
+ BLOCKTYPE BelowBlock;
+ NIBBLETYPE BelowBlockMeta;
+ a_Chunk.GetBlockTypeMeta(BelowPos, BelowBlock, BelowBlockMeta);
+
+ if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
+ {
+ return true;
+ }
+
+ // upside down slabs
+ if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
+ {
+ return BelowBlockMeta & E_META_WOODEN_SLAB_UPSIDE_DOWN;
+ }
+
+ // upside down stairs
+ if (cBlockStairsHandler::IsAnyStairType(BelowBlock))
+ {
+ return BelowBlockMeta & E_BLOCK_STAIRS_UPSIDE_DOWN;
+ }
+
+ return false;
+ }
+};
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/ChunkMap.cpp b/src/ChunkMap.cpp
index a2bc50fe9..d982d0cf3 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -474,6 +474,11 @@ void cChunkMap::CollectPickupsByEntity(cEntity & a_Entity)
BLOCKTYPE cChunkMap::GetBlock(Vector3i a_BlockPos) const
{
+ if (!cChunkDef::IsValidHeight(a_BlockPos))
+ {
+ return 0;
+ }
+
auto chunkPos = cChunkDef::BlockToChunk(a_BlockPos);
auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkPos);
@@ -493,6 +498,11 @@ BLOCKTYPE cChunkMap::GetBlock(Vector3i a_BlockPos) const
NIBBLETYPE cChunkMap::GetBlockMeta(Vector3i a_BlockPos) const
{
+ if (!cChunkDef::IsValidHeight(a_BlockPos))
+ {
+ return 0;
+ }
+
auto chunkPos = cChunkDef::BlockToChunk(a_BlockPos);
auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkPos);
@@ -585,6 +595,14 @@ void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE
bool cChunkMap::GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
{
+ if (!cChunkDef::IsValidHeight(a_BlockPos))
+ {
+ // Initialise the params to fulfil our contract.
+ a_BlockType = 0;
+ a_BlockMeta = 0;
+ return false;
+ }
+
auto chunkCoord = cChunkDef::BlockToChunk(a_BlockPos);
auto relPos = cChunkDef::AbsoluteToRelative(a_BlockPos, chunkCoord);
@@ -595,6 +613,10 @@ bool cChunkMap::GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, N
Chunk->GetBlockTypeMeta(relPos, a_BlockType, a_BlockMeta);
return true;
}
+
+ // Initialise the params to fulfil our contract.
+ a_BlockType = 0;
+ a_BlockMeta = 0;
return false;
}
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index 578c49b8a..8538b7624 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -115,6 +115,10 @@ public:
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_BlockMeta);
void SetBlock (Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+ /** Get the block type and meta at the specified coords
+ Will always initialise a_BlockType and a_BlockMeta if called.
+ Returns false if the data could not be retrieved, either because the chunk is invalid or the height is invalid.
+ Otherwise, returns true. */
bool GetBlockTypeMeta (Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
bool GetBlockInfo (Vector3i, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight) const;
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index b726e5c6f..2b32c5c07 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -74,6 +74,7 @@ cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) :
m_IPString(a_IPString),
m_Player(nullptr),
m_CachedSentChunk(std::numeric_limits<decltype(m_CachedSentChunk.m_ChunkX)>::max(), std::numeric_limits<decltype(m_CachedSentChunk.m_ChunkZ)>::max()),
+ m_ProxyConnection(false),
m_HasSentDC(false),
m_LastStreamedChunkX(std::numeric_limits<decltype(m_LastStreamedChunkX)>::max()), // bogus chunk coords to force streaming upon login
m_LastStreamedChunkZ(std::numeric_limits<decltype(m_LastStreamedChunkZ)>::max()),
@@ -1253,7 +1254,10 @@ void cClientHandle::HandleBlockDigStarted(Vector3i a_BlockPos, eBlockFace a_Bloc
BLOCKTYPE DiggingBlock;
NIBBLETYPE DiggingMeta;
- m_Player->GetWorld()->GetBlockTypeMeta(a_BlockPos, DiggingBlock, DiggingMeta);
+ if (!m_Player->GetWorld()->GetBlockTypeMeta(a_BlockPos, DiggingBlock, DiggingMeta))
+ {
+ return;
+ }
if (
m_Player->IsGameModeCreative() &&
@@ -1321,7 +1325,10 @@ void cClientHandle::HandleBlockDigFinished(Vector3i a_BlockPos, eBlockFace a_Blo
BLOCKTYPE DugBlock;
NIBBLETYPE DugMeta;
- m_Player->GetWorld()->GetBlockTypeMeta(a_BlockPos, DugBlock, DugMeta);
+ if (!m_Player->GetWorld()->GetBlockTypeMeta(a_BlockPos, DugBlock, DugMeta))
+ {
+ return;
+ }
if (!m_Player->IsGameModeCreative())
{
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/Entities/Player.cpp b/src/Entities/Player.cpp
index c580d8293..50fd034a5 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -982,6 +982,13 @@ void cPlayer::Respawn(void)
TeleportToCoords(m_RespawnPosition.x, m_RespawnPosition.y, m_RespawnPosition.z);
}
+ // The Notchian client enters a weird glitched state when trying to "resurrect" dead players
+ // To prevent that, destroy the existing client-side entity, and create a new one with the same ID
+ // This does not make any difference to more modern clients
+ m_World->BroadcastDestroyEntity(*this, &*m_ClientHandle);
+ m_World->BroadcastSpawnEntity(*this, &*m_ClientHandle);
+
+
SetVisible(true);
}
@@ -2587,9 +2594,10 @@ bool cPlayer::IsInsideWater()
BLOCKTYPE Block;
NIBBLETYPE Meta;
- m_World->GetBlockTypeMeta(EyePos, Block, Meta);
-
- if ((Block != E_BLOCK_WATER) && (Block != E_BLOCK_STATIONARY_WATER))
+ if (
+ !m_World->GetBlockTypeMeta(GetEyePosition().Floor(), Block, Meta) ||
+ ((Block != E_BLOCK_WATER) && (Block != E_BLOCK_STATIONARY_WATER))
+ )
{
return false;
}
diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp
index 967a4a89c..fb7b89422 100644
--- a/src/Generating/CompoGenBiomal.cpp
+++ b/src/Generating/CompoGenBiomal.cpp
@@ -456,7 +456,10 @@ protected:
}
HasHadWater = true;
} // for y
- a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
+ if (a_ShapeColumn[0] > 0)
+ {
+ a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
+ }
}
diff --git a/src/Items/ItemBed.h b/src/Items/ItemBed.h
index a2e254171..77818e7c7 100644
--- a/src/Items/ItemBed.h
+++ b/src/Items/ItemBed.h
@@ -27,7 +27,10 @@ public:
auto & World = *a_Player.GetWorld();
BLOCKTYPE HeadType;
NIBBLETYPE HeadMeta;
- World.GetBlockTypeMeta(HeadPosition, HeadType, HeadMeta);
+ if (!World.GetBlockTypeMeta(HeadPosition, HeadType, HeadMeta))
+ {
+ return false;
+ }
// Vanilla only allows beds to be placed into air.
// Check if there is empty space for the "head" block:
diff --git a/src/Items/ItemBigFlower.h b/src/Items/ItemBigFlower.h
index cbdecbed7..a135a220d 100644
--- a/src/Items/ItemBigFlower.h
+++ b/src/Items/ItemBigFlower.h
@@ -29,7 +29,10 @@ public:
const auto TopPos = a_PlacePosition.addedY(1);
BLOCKTYPE TopType;
NIBBLETYPE TopMeta;
- World.GetBlockTypeMeta(TopPos, TopType, TopMeta);
+ if (!World.GetBlockTypeMeta(TopPos, TopType, TopMeta))
+ {
+ return false;
+ }
if (!cBlockHandler::For(TopType).DoesIgnoreBuildCollision(World, a_HeldItem, TopPos, TopMeta, a_ClickedBlockFace, false))
{
diff --git a/src/Items/ItemDoor.h b/src/Items/ItemDoor.h
index 6538a5bef..f28d3ad36 100644
--- a/src/Items/ItemDoor.h
+++ b/src/Items/ItemDoor.h
@@ -54,7 +54,10 @@ public:
{
BLOCKTYPE TopType;
NIBBLETYPE TopMeta;
- World.GetBlockTypeMeta(UpperBlockPosition, TopType, TopMeta);
+ if (!World.GetBlockTypeMeta(UpperBlockPosition, TopType, TopMeta))
+ {
+ return false;
+ }
if (!cBlockHandler::For(TopType).DoesIgnoreBuildCollision(World, a_HeldItem, UpperBlockPosition, TopMeta, a_ClickedBlockFace, false))
{
diff --git a/src/Items/ItemDye.h b/src/Items/ItemDye.h
index 636a1b477..b0f00b9ba 100644
--- a/src/Items/ItemDye.h
+++ b/src/Items/ItemDye.h
@@ -54,10 +54,12 @@ public:
// Cocoa (brown dye) can be planted on jungle logs:
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- a_World->GetBlockTypeMeta(a_ClickedBlockPos, BlockType, BlockMeta);
// Check if the block that the player clicked is a jungle log.
- if ((BlockType != E_BLOCK_LOG) || ((BlockMeta & 0x03) != E_META_LOG_JUNGLE))
+ if (
+ !a_World->GetBlockTypeMeta(a_ClickedBlockPos, BlockType, BlockMeta) ||
+ ((BlockType != E_BLOCK_LOG) || ((BlockMeta & 0x03) != E_META_LOG_JUNGLE))
+ )
{
return false;
}
diff --git a/src/Items/ItemEyeOfEnder.h b/src/Items/ItemEyeOfEnder.h
index fc6fac336..414d81c39 100644
--- a/src/Items/ItemEyeOfEnder.h
+++ b/src/Items/ItemEyeOfEnder.h
@@ -35,8 +35,8 @@ public:
{
BLOCKTYPE FacingBlock;
NIBBLETYPE FacingMeta;
- a_World->GetBlockTypeMeta(a_ClickedBlockPos, FacingBlock, FacingMeta);
- if (FacingBlock == E_BLOCK_END_PORTAL_FRAME)
+
+ if (a_World->GetBlockTypeMeta(a_ClickedBlockPos, FacingBlock, FacingMeta) && (FacingBlock == E_BLOCK_END_PORTAL_FRAME))
{
// Fill the portal frame. E_META_END_PORTAL_EYE is the bit for holding the eye of ender.
if ((FacingMeta & E_META_END_PORTAL_FRAME_EYE) != E_META_END_PORTAL_FRAME_EYE)
diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h
index 2bca5f5ca..503047328 100644
--- a/src/Items/ItemHoe.h
+++ b/src/Items/ItemHoe.h
@@ -46,7 +46,10 @@ public:
// Can only transform dirt or grass blocks:
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- a_World->GetBlockTypeMeta(a_ClickedBlockPos, BlockType, BlockMeta);
+ if (!a_World->GetBlockTypeMeta(a_ClickedBlockPos, BlockType, BlockMeta))
+ {
+ return false;
+ }
if ((BlockType != E_BLOCK_DIRT) && (BlockType != E_BLOCK_GRASS))
{
return false;
diff --git a/src/Items/ItemShears.h b/src/Items/ItemShears.h
index 5f8e9e2f1..00504884c 100644
--- a/src/Items/ItemShears.h
+++ b/src/Items/ItemShears.h
@@ -32,7 +32,10 @@ public:
{
BLOCKTYPE Block;
NIBBLETYPE BlockMeta;
- a_World->GetBlockTypeMeta(a_ClickedBlockPos, Block, BlockMeta);
+ if (!a_World->GetBlockTypeMeta(a_ClickedBlockPos, Block, BlockMeta))
+ {
+ return false;
+ }
if ((Block == E_BLOCK_LEAVES) || (Block == E_BLOCK_NEW_LEAVES))
{
diff --git a/src/Map.cpp b/src/Map.cpp
index 9e3c364b1..3691d0ab0 100644
--- a/src/Map.cpp
+++ b/src/Map.cpp
@@ -23,6 +23,7 @@ cMap::cMap(unsigned int a_ID, cWorld * a_World):
m_Scale(3),
m_CenterX(0),
m_CenterZ(0),
+ m_Dirty(false), // This constructor is for an empty map object which will be filled by the caller with the correct values - it does not need saving.
m_World(a_World),
m_Name(fmt::format(FMT_STRING("map_{}"), m_ID))
{
@@ -40,6 +41,7 @@ cMap::cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, un
m_Scale(a_Scale),
m_CenterX(a_CenterX),
m_CenterZ(a_CenterZ),
+ m_Dirty(true), // This constructor is for creating a brand new map in game, it will always need saving.
m_World(a_World),
m_Name(fmt::format(FMT_STRING("map_{}"), m_ID))
{
@@ -223,7 +225,13 @@ bool cMap::SetPixel(unsigned int a_X, unsigned int a_Z, cMap::ColorID a_Data)
{
if ((a_X < m_Width) && (a_Z < m_Height))
{
- m_Data[a_Z * m_Width + a_X] = a_Data;
+ auto index = a_Z * m_Width + a_X;
+
+ if (m_Data[index] != a_Data)
+ {
+ m_Data[index] = a_Data;
+ m_Dirty = true;
+ }
return true;
}
diff --git a/src/Map.h b/src/Map.h
index 493b0883e..645f84c08 100644
--- a/src/Map.h
+++ b/src/Map.h
@@ -185,6 +185,8 @@ private:
int m_CenterX;
int m_CenterZ;
+ bool m_Dirty;
+
/** Column-major array of colours */
cColorList m_Data;
@@ -196,6 +198,7 @@ private:
AString m_Name;
+ friend class cMapManager;
friend class cMapSerializer;
}; // tolua_export
diff --git a/src/MapManager.cpp b/src/MapManager.cpp
index ae020d800..f7b393648 100644
--- a/src/MapManager.cpp
+++ b/src/MapManager.cpp
@@ -12,8 +12,16 @@
-cMapManager::cMapManager(cWorld * a_World)
- : m_World(a_World)
+// 6000 ticks or 5 minutes
+#define MAP_DATA_SAVE_INTERVAL 6000
+
+
+
+
+
+cMapManager::cMapManager(cWorld * a_World) :
+ m_World(a_World),
+ m_TicksUntilNextSave(MAP_DATA_SAVE_INTERVAL)
{
ASSERT(m_World != nullptr);
}
@@ -49,6 +57,16 @@ void cMapManager::TickMaps()
{
Map.Tick();
}
+
+ if (m_TicksUntilNextSave == 0)
+ {
+ m_TicksUntilNextSave = MAP_DATA_SAVE_INTERVAL;
+ SaveMapData();
+ }
+ else
+ {
+ m_TicksUntilNextSave--;
+ }
}
@@ -149,11 +167,18 @@ void cMapManager::SaveMapData(void)
{
cMap & Map = *it;
- cMapSerializer Serializer(m_World->GetDataPath(), &Map);
-
- if (!Serializer.Save())
+ if (Map.m_Dirty)
{
- LOGWARN("Could not save map #%i", Map.GetID());
+ cMapSerializer Serializer(m_World->GetDataPath(), &Map);
+
+ if (Serializer.Save())
+ {
+ Map.m_Dirty = false;
+ }
+ else
+ {
+ LOGWARN("Could not save map #%i", Map.GetID());
+ }
}
}
}
diff --git a/src/MapManager.h b/src/MapManager.h
index 8959b1d8b..d20fe6683 100644
--- a/src/MapManager.h
+++ b/src/MapManager.h
@@ -64,6 +64,10 @@ private:
cWorld * m_World;
+ /** How long till the map data will be saved
+ Default save interval is #defined in MAP_DATA_SAVE_INTERVAL */
+ unsigned int m_TicksUntilNextSave;
+
}; // tolua_export
diff --git a/src/Noise/InterpolNoise.h b/src/Noise/InterpolNoise.h
index 447796739..12b167dbe 100644
--- a/src/Noise/InterpolNoise.h
+++ b/src/Noise/InterpolNoise.h
@@ -427,28 +427,37 @@ public:
// Calculate query values using Cell:
int FromZ = 0;
- for (int z = 0; z < NumSameZ; z++)
+ for (int z = 0; z < NumSameZ;)
{
int ToZ = FromZ + SameZ[z];
int CurFloorZ = FloorZ[FromZ];
int FromY = 0;
- for (int y = 0; y < NumSameY; y++)
+ for (int y = 0; y < NumSameY;)
{
int ToY = FromY + SameY[y];
int CurFloorY = FloorY[FromY];
int FromX = 0;
- for (int x = 0; x < NumSameX; x++)
+ for (int x = 0; x < NumSameX;)
{
int ToX = FromX + SameX[x];
Cell.Generate(FromX, ToX, FromY, ToY, FromZ, ToZ);
- Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ);
- FromX = ToX;
+ if (++x < NumSameX) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ);
+ FromX = ToX;
+ }
+ }
+ if (++y < NumSameY) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ);
+ FromY = ToY;
}
- Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ);
- FromY = ToY;
} // for y
- Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]);
- FromZ = ToZ;
+ if (++z < NumSameZ) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]);
+ FromZ = ToZ;
+ }
} // for z
}
diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp
index cbdc6bc72..136d124a0 100644
--- a/src/Noise/Noise.cpp
+++ b/src/Noise/Noise.cpp
@@ -734,20 +734,26 @@ void cCubicNoise::Generate2D(
// Calculate query values using Cell:
int FromY = 0;
- for (int y = 0; y < NumSameY; y++)
+ for (int y = 0; y < NumSameY;)
{
int ToY = FromY + SameY[y];
int FromX = 0;
int CurFloorY = FloorY[FromY];
- for (int x = 0; x < NumSameX; x++)
+ for (int x = 0; x < NumSameX;)
{
int ToX = FromX + SameX[x];
Cell.Generate(FromX, ToX, FromY, ToY);
- Cell.Move(FloorX[ToX], CurFloorY);
- FromX = ToX;
+ if (++x < NumSameX) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[ToX], CurFloorY);
+ FromX = ToX;
+ }
+ }
+ if (++y < NumSameY) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[0], FloorY[ToY]);
+ FromY = ToY;
}
- Cell.Move(FloorX[0], FloorY[ToY]);
- FromY = ToY;
}
}
@@ -795,28 +801,37 @@ void cCubicNoise::Generate3D(
// Calculate query values using Cell:
int FromZ = 0;
- for (int z = 0; z < NumSameZ; z++)
+ for (int z = 0; z < NumSameZ;)
{
int ToZ = FromZ + SameZ[z];
int CurFloorZ = FloorZ[FromZ];
int FromY = 0;
- for (int y = 0; y < NumSameY; y++)
+ for (int y = 0; y < NumSameY;)
{
int ToY = FromY + SameY[y];
int CurFloorY = FloorY[FromY];
int FromX = 0;
- for (int x = 0; x < NumSameX; x++)
+ for (int x = 0; x < NumSameX;)
{
int ToX = FromX + SameX[x];
Cell.Generate(FromX, ToX, FromY, ToY, FromZ, ToZ);
- Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ);
- FromX = ToX;
+ if (++x < NumSameX) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[ToX], CurFloorY, CurFloorZ);
+ FromX = ToX;
+ }
+ }
+ if (++y < NumSameY) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ);
+ FromY = ToY;
}
- Cell.Move(FloorX[0], FloorY[ToY], CurFloorZ);
- FromY = ToY;
} // for y
- Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]);
- FromZ = ToZ;
+ if (++z < NumSameZ) // Call Move() every time except for the last loop iteration
+ {
+ Cell.Move(FloorX[0], FloorY[0], FloorZ[ToZ]);
+ FromZ = ToZ;
+ }
} // for z
}
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/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 4085dc816..ef5f7382e 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -1065,9 +1065,12 @@ void cSlotAreaAnvil::OnTakeResult(cPlayer & a_Player)
BLOCKTYPE Block;
NIBBLETYPE BlockMeta;
- a_Player.GetWorld()->GetBlockTypeMeta(BlockPos, Block, BlockMeta);
- if (!a_Player.IsGameModeCreative() && (Block == E_BLOCK_ANVIL) && GetRandomProvider().RandBool(0.12))
+ if (
+ a_Player.GetWorld()->GetBlockTypeMeta(BlockPos, Block, BlockMeta) &&
+ !a_Player.IsGameModeCreative() && (Block == E_BLOCK_ANVIL) &&
+ GetRandomProvider().RandBool(0.12)
+ )
{
NIBBLETYPE Orientation = BlockMeta & 0x3;
NIBBLETYPE AnvilDamage = BlockMeta >> 2;
diff --git a/src/Vector3.h b/src/Vector3.h
index 0e275e9b3..5df14b3ac 100644
--- a/src/Vector3.h
+++ b/src/Vector3.h
@@ -30,13 +30,20 @@ public:
// tolua_end
// Conversion constructors where U is not the same as T leaving the copy-constructor implicitly generated
- template <typename U, typename = typename std::enable_if<!std::is_same<U, T>::value>::type>
+ template <typename U, std::enable_if_t<(!std::is_same<U, T>::value) && ((!std::is_integral<T>::value) || (std::is_integral<U>::value)), bool> = true>
constexpr Vector3(const Vector3<U> & a_Rhs):
x(static_cast<T>(a_Rhs.x)),
y(static_cast<T>(a_Rhs.y)),
z(static_cast<T>(a_Rhs.z))
{
}
+ template <typename U, std::enable_if_t<(!std::is_same<U, T>::value) && ((std::is_integral<T>::value) && (!std::is_integral<U>::value)), bool> = true>
+ constexpr Vector3(const Vector3<U> & a_Rhs):
+ x(static_cast<T>(std::floor(a_Rhs.x))),
+ y(static_cast<T>(std::floor(a_Rhs.y))),
+ z(static_cast<T>(std::floor(a_Rhs.z)))
+ {
+ }
// tolua_begin
inline void Set(T a_x, T a_y, T a_z)
diff --git a/src/World.cpp b/src/World.cpp
index 2f92020bf..781d44c3a 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1539,8 +1539,7 @@ bool cWorld::GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_Meta)
{
NIBBLETYPE meta;
BLOCKTYPE type;
- GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
- IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
+ IsLarge = IsLarge && GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta) && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
@@ -1557,8 +1556,7 @@ bool cWorld::GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_Meta)
{
NIBBLETYPE meta;
BLOCKTYPE type;
- GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
- IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
+ IsLarge = IsLarge && GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta) && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
@@ -1576,8 +1574,7 @@ bool cWorld::GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_Meta)
{
NIBBLETYPE meta;
BLOCKTYPE type;
- GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
- IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
+ IsLarge = IsLarge && GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta) && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
@@ -1596,8 +1593,7 @@ bool cWorld::GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_Meta)
{
NIBBLETYPE meta;
BLOCKTYPE type;
- GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
- IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
+ IsLarge = IsLarge && GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta) && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
@@ -2044,7 +2040,10 @@ void cWorld::PlaceBlock(const Vector3i a_Position, const BLOCKTYPE a_BlockType,
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- GetBlockTypeMeta(a_Position, BlockType, BlockMeta);
+ if (!GetBlockTypeMeta(a_Position, BlockType, BlockMeta))
+ {
+ return;
+ }
SetBlock(a_Position, a_BlockType, a_BlockMeta);
@@ -2070,7 +2069,10 @@ bool cWorld::DigBlock(Vector3i a_BlockPos, const cEntity * a_Digger)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
- GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta);
+ if (!GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta))
+ {
+ return false;
+ }
if (!m_ChunkMap.DigBlock(a_BlockPos))
{
@@ -2617,7 +2619,11 @@ bool cWorld::IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ)
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
- GetBlockTypeMeta({ a_BlockX, a_BlockY, a_BlockZ }, Block, Meta);
+ if (!GetBlockTypeMeta({ a_BlockX, a_BlockY, a_BlockZ }, Block, Meta))
+ {
+ return false;
+ }
+
if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR))
{
return false;
@@ -2634,7 +2640,11 @@ bool cWorld::SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Op
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
- GetBlockTypeMeta({ a_BlockX, a_BlockY, a_BlockZ }, Block, Meta);
+ if (!GetBlockTypeMeta({ a_BlockX, a_BlockY, a_BlockZ }, Block, Meta))
+ {
+ return false;
+ }
+
if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR))
{
return false;
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())
{
diff --git a/src/mbedTLS++/CryptoKey.cpp b/src/mbedTLS++/CryptoKey.cpp
index 742d9c73c..ea01bfc80 100644
--- a/src/mbedTLS++/CryptoKey.cpp
+++ b/src/mbedTLS++/CryptoKey.cpp
@@ -124,15 +124,18 @@ int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AStri
if (a_Password.empty())
{
- return mbedtls_pk_parse_key(&m_Pk, reinterpret_cast<const unsigned char *>(keyData.data()), a_NumBytes + 1, nullptr, 0, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal());
+ return mbedtls_pk_parse_key(
+ &m_Pk,
+ reinterpret_cast<const unsigned char *>(keyData.data()), a_NumBytes + 1,
+ nullptr, 0
+ );
}
else
{
return mbedtls_pk_parse_key(
&m_Pk,
reinterpret_cast<const unsigned char *>(keyData.data()), a_NumBytes + 1,
- reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size(),
- mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
+ reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size()
);
}
}
diff --git a/src/mbedTLS++/RsaPrivateKey.cpp b/src/mbedTLS++/RsaPrivateKey.cpp
index d0c5b7c8b..81cd2db44 100644
--- a/src/mbedTLS++/RsaPrivateKey.cpp
+++ b/src/mbedTLS++/RsaPrivateKey.cpp
@@ -11,7 +11,7 @@
cRsaPrivateKey::cRsaPrivateKey(void)
{
- mbedtls_rsa_init(&m_Rsa);
+ mbedtls_rsa_init(&m_Rsa, MBEDTLS_RSA_PKCS_V15, 0);
m_CtrDrbg.Initialize("RSA", 3);
}
@@ -21,7 +21,7 @@ cRsaPrivateKey::cRsaPrivateKey(void)
cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other)
{
- mbedtls_rsa_init(&m_Rsa);
+ mbedtls_rsa_init(&m_Rsa, MBEDTLS_RSA_PKCS_V15, 0);
mbedtls_rsa_copy(&m_Rsa, &a_Other.m_Rsa);
m_CtrDrbg.Initialize("RSA", 3);
}
@@ -122,7 +122,7 @@ int cRsaPrivateKey::Decrypt(const ContiguousByteBufferView a_EncryptedData, Byte
}
size_t DecryptedLength;
int res = mbedtls_rsa_pkcs1_decrypt(
- &m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), &DecryptedLength,
+ &m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), MBEDTLS_RSA_PRIVATE, &DecryptedLength,
reinterpret_cast<const unsigned char *>(a_EncryptedData.data()), a_DecryptedData, a_DecryptedMaxLength
);
if (res != 0)
diff --git a/tests/CompositeChat/CompositeChatTest.cpp b/tests/CompositeChat/CompositeChatTest.cpp
index ca05e79a2..9bc1c31b2 100644
--- a/tests/CompositeChat/CompositeChatTest.cpp
+++ b/tests/CompositeChat/CompositeChatTest.cpp
@@ -109,6 +109,7 @@ static void TestParser5(void)
+
static void TestParser6(void)
{
cCompositeChat Msg;
diff --git a/tests/HTTP/UrlClientTest.cpp b/tests/HTTP/UrlClientTest.cpp
index 44e39e666..eeeaf774b 100644
--- a/tests/HTTP/UrlClientTest.cpp
+++ b/tests/HTTP/UrlClientTest.cpp
@@ -204,35 +204,35 @@ namespace TrustedCAs
// The root cert used by cuberite.org
static const char CuberiteOrg[] =
"-----BEGIN CERTIFICATE-----\n"
- "MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/\n"
- "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
- "DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow\n"
+ "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
- "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB\n"
- "AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC\n"
- "ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL\n"
- "wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D\n"
- "LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK\n"
- "4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5\n"
- "bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y\n"
- "sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ\n"
- "Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4\n"
- "FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc\n"
- "SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql\n"
- "PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND\n"
- "TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n"
- "SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1\n"
- "c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx\n"
- "+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB\n"
- "ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu\n"
- "b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E\n"
- "U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu\n"
- "MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC\n"
- "5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW\n"
- "9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG\n"
- "WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O\n"
- "he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC\n"
- "Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5\n"
+ "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n"
+ "WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n"
+ "ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n"
+ "MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n"
+ "h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n"
+ "0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\n"
+ "A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\n"
+ "T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\n"
+ "B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\n"
+ "B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\n"
+ "KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\n"
+ "OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\n"
+ "jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\n"
+ "qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\n"
+ "rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"
+ "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\n"
+ "hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\n"
+ "ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\n"
+ "3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\n"
+ "NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\n"
+ "ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\n"
+ "TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\n"
+ "jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\n"
+ "oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n"
+ "4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\n"
+ "mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n"
+ "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
"-----END CERTIFICATE-----\n";
}