summaryrefslogtreecommitdiffstats
path: root/src/BlockTypePalette.cpp
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2020-09-08 10:46:16 +0200
committerTiger Wang <ziwei.tiger@outlook.com>2020-12-21 01:11:34 +0100
commit742e27ad2f037205285e475be487ec9ed874ca91 (patch)
tree3218d3c2791e823c88a294ba7fdb10035c8fbb9b /src/BlockTypePalette.cpp
parentEnable LOS checks for Hostile Mobs. (diff)
downloadcuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.gz
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.bz2
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.lz
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.xz
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.zst
cuberite-742e27ad2f037205285e475be487ec9ed874ca91.zip
Diffstat (limited to 'src/BlockTypePalette.cpp')
-rw-r--r--src/BlockTypePalette.cpp380
1 files changed, 0 insertions, 380 deletions
diff --git a/src/BlockTypePalette.cpp b/src/BlockTypePalette.cpp
deleted file mode 100644
index 7759505cf..000000000
--- a/src/BlockTypePalette.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-#include "Globals.h"
-#include "BlockTypePalette.h"
-#include "json/value.h"
-#include "JsonUtils.h"
-
-
-
-
-
-/** Returns the index into aString >= aStartIdx at which the next separator occurs.
-Separator is one of \t, \n or \r.
-Returns AString::npos if no such separator. */
-static size_t findNextSeparator(const AString & aString, size_t aStartIdx = 0)
-{
- for (size_t i = aStartIdx, len = aString.length(); i < len; ++i)
- {
- switch (aString[i])
- {
- case '\t':
- case '\n':
- case '\r':
- {
- return i;
- }
- }
- }
- return AString::npos;
-}
-
-
-
-
-
-BlockTypePalette::BlockTypePalette():
- mMaxIndex(0)
-{
-}
-
-
-
-
-
-UInt32 BlockTypePalette::index(const AString & aBlockTypeName, const BlockState & aBlockState)
-{
- auto idx = maybeIndex(aBlockTypeName, aBlockState);
- if (idx.second)
- {
- return idx.first;
- }
-
- // Not found, append:
- auto index = mMaxIndex++;
- mBlockToNumber[aBlockTypeName][aBlockState] = index;
- mNumberToBlock[index] = {aBlockTypeName, aBlockState};
- return index;
-}
-
-
-
-
-
-std::pair<UInt32, bool> BlockTypePalette::maybeIndex(const AString & aBlockTypeName, const BlockState & aBlockState) const
-{
- auto itr1 = mBlockToNumber.find(aBlockTypeName);
- if (itr1 == mBlockToNumber.end())
- {
- return {0, false};
- }
- auto itr2 = itr1->second.find(aBlockState);
- if (itr2 == itr1->second.end())
- {
- return {0, false};
- }
- return {itr2->second, true};
-}
-
-
-
-
-
-UInt32 BlockTypePalette::count() const
-{
- return static_cast<UInt32>(mNumberToBlock.size());
-}
-
-
-
-
-
-const std::pair<AString, BlockState> & BlockTypePalette::entry(UInt32 aIndex) const
-{
- auto itr = mNumberToBlock.find(aIndex);
- if (itr == mNumberToBlock.end())
- {
- throw NoSuchIndexException(aIndex);
- }
- return itr->second;
-}
-
-
-
-
-
-std::map<UInt32, UInt32> BlockTypePalette::createTransformMapAddMissing(const BlockTypePalette & aFrom)
-{
- std::map<UInt32, UInt32> res;
- for (const auto & fromEntry: aFrom.mNumberToBlock)
- {
- auto fromIndex = fromEntry.first;
- const auto & blockTypeName = fromEntry.second.first;
- const auto & blockState = fromEntry.second.second;
- res[fromIndex] = index(blockTypeName, blockState);
- }
- return res;
-}
-
-
-
-
-
-std::map<UInt32, UInt32> BlockTypePalette::createTransformMapWithFallback(const BlockTypePalette & aFrom, UInt32 aFallbackIndex) const
-{
- std::map<UInt32, UInt32> res;
- for (const auto & fromEntry: aFrom.mNumberToBlock)
- {
- auto fromIndex = fromEntry.first;
- const auto & blockTypeName = fromEntry.second.first;
- const auto & blockState = fromEntry.second.second;
- auto thisIndex = maybeIndex(blockTypeName, blockState);
- if (thisIndex.second)
- {
- // The entry was found in this
- res[fromIndex] = thisIndex.first;
- }
- else
- {
- // The entry was NOT found in this, replace with fallback:
- res[fromIndex] = aFallbackIndex;
- }
- }
- return res;
-}
-
-
-
-
-
-void BlockTypePalette::loadFromString(const AString & aString)
-{
- static const AString hdrTsvRegular = "BlockTypePalette";
- static const AString hdrTsvUpgrade = "UpgradeBlockTypePalette";
-
- // Detect format by checking the header line (none -> JSON):
- if (aString.substr(0, hdrTsvRegular.length()) == hdrTsvRegular)
- {
- return loadFromTsv(aString, false);
- }
- else if (aString.substr(0, hdrTsvUpgrade.length()) == hdrTsvUpgrade)
- {
- return loadFromTsv(aString, true);
- }
- return loadFromJsonString(aString);
-}
-
-
-
-
-
-void BlockTypePalette::loadFromJsonString(const AString & aJsonPalette)
-{
- // Parse the string into JSON object:
- Json::Value root;
- std::string errs;
- if (!JsonUtils::ParseString(aJsonPalette, root, &errs))
- {
- throw LoadFailedException(errs);
- }
-
- // Sanity-check the JSON's structure:
- if (!root.isObject())
- {
- throw LoadFailedException("Incorrect palette format, expected an object at root.");
- }
-
- // Load the palette:
- for (auto itr = root.begin(), end = root.end(); itr != end; ++itr)
- {
- const auto & blockTypeName = itr.name();
- const auto & states = (*itr)["states"];
- if (states == Json::Value())
- {
- throw LoadFailedException(Printf("Missing \"states\" for block type \"%s\"", blockTypeName));
- }
- for (const auto & state: states)
- {
- auto id = static_cast<UInt32>(std::stoul(state["id"].asString()));
- std::map<AString, AString> props;
- if (state.isMember("properties"))
- {
- const auto & properties = state["properties"];
- if (!properties.isObject())
- {
- throw LoadFailedException(Printf("Member \"properties\" is not a JSON object (block type \"%s\", id %u).", blockTypeName, id));
- }
- for (const auto & key: properties.getMemberNames())
- {
- props[key] = properties[key].asString();
- }
- }
- addMapping(id, blockTypeName, props);
- }
- }
-}
-
-
-
-
-
-void BlockTypePalette::loadFromTsv(const AString & aTsvPalette, bool aIsUpgrade)
-{
- static const AString hdrTsvRegular = "BlockTypePalette";
- static const AString hdrTsvUpgrade = "UpgradeBlockTypePalette";
-
- // Check the file signature:
- auto idx = findNextSeparator(aTsvPalette);
- if ((idx == AString::npos) || (aTsvPalette[idx] == '\t'))
- {
- throw LoadFailedException("Invalid signature");
- }
- auto signature = aTsvPalette.substr(0, idx);
- bool isUpgrade = (signature == hdrTsvUpgrade);
- if (!isUpgrade && (signature != hdrTsvRegular))
- {
- throw LoadFailedException("Unknown signature");
- }
- if (aTsvPalette[idx] == '\r') // CR of the CRLF pair, skip the LF:
- {
- idx += 1;
- }
-
- // Parse the header:
- bool hasHadVersion = false;
- AString commonPrefix;
- int line = 2;
- auto len = aTsvPalette.length();
- while (true)
- {
- auto keyStart = idx + 1;
- auto keyEnd = findNextSeparator(aTsvPalette, idx + 1);
- if (keyEnd == AString::npos)
- {
- throw LoadFailedException(Printf("Invalid header key format on line %u", line));
- }
- if (keyEnd == idx + 1) // Empty line, end of headers
- {
- if (aTsvPalette[keyEnd] == '\r') // CR of the CRLF pair, skip the LF:
- {
- ++keyEnd;
- }
- idx = keyEnd;
- ++line;
- break;
- }
- auto valueEnd = findNextSeparator(aTsvPalette, keyEnd + 1);
- if ((valueEnd == AString::npos) || (aTsvPalette[valueEnd] == '\t'))
- {
- throw LoadFailedException(Printf("Invalid header value format on line %u", line));
- }
- auto key = aTsvPalette.substr(keyStart, keyEnd - keyStart);
- if (key == "FileVersion")
- {
- unsigned version = 0;
- auto value = aTsvPalette.substr(keyEnd + 1, valueEnd - keyEnd - 1);
- if (!StringToInteger(value, version))
- {
- throw LoadFailedException("Invalid FileVersion value");
- }
- else if (version != 1)
- {
- throw LoadFailedException(Printf("Unknown FileVersion: %u. Only version 1 is supported.", version));
- }
- hasHadVersion = true;
- }
- else if (key == "CommonPrefix")
- {
- commonPrefix = aTsvPalette.substr(keyEnd + 1, valueEnd - keyEnd - 1);
- }
- idx = valueEnd;
- if (aTsvPalette[idx] == '\r') // CR of the CRLF pair, skip the LF:
- {
- ++idx;
- }
- ++line;
- }
- if (!hasHadVersion)
- {
- throw LoadFailedException("No FileVersion value");
- }
-
- // Parse the data:
- while (idx + 1 < len)
- {
- auto lineStart = idx + 1;
- auto idEnd = findNextSeparator(aTsvPalette, lineStart);
- if ((idEnd == AString::npos) || (aTsvPalette[idEnd] != '\t'))
- {
- throw LoadFailedException(Printf("Incomplete data on line %u (id)", line));
- }
- UInt32 id;
- if (!StringToInteger(aTsvPalette.substr(lineStart, idEnd - lineStart), id))
- {
- throw LoadFailedException(Printf("Failed to parse id on line %u", line));
- }
- size_t metaEnd = idEnd;
- if (isUpgrade)
- {
- metaEnd = findNextSeparator(aTsvPalette, idEnd + 1);
- if ((metaEnd == AString::npos) || (aTsvPalette[metaEnd] != '\t'))
- {
- throw LoadFailedException(Printf("Incomplete data on line %u (meta)", line));
- }
- UInt32 meta = 0;
- if (!StringToInteger(aTsvPalette.substr(idEnd + 1, metaEnd - idEnd - 1), meta))
- {
- throw LoadFailedException(Printf("Failed to parse meta on line %u", line));
- }
- if (meta > 15)
- {
- throw LoadFailedException(Printf("Invalid meta value on line %u: %u", line, meta));
- }
- id = (id * 16) | meta;
- }
- auto blockTypeEnd = findNextSeparator(aTsvPalette, metaEnd + 1);
- if (blockTypeEnd == AString::npos)
- {
- throw LoadFailedException(Printf("Incomplete data on line %u (blockTypeName)", line));
- }
- auto blockTypeName = aTsvPalette.substr(metaEnd + 1, blockTypeEnd - metaEnd - 1);
- auto blockStateEnd = blockTypeEnd;
- AStringMap blockState;
- while (aTsvPalette[blockStateEnd] == '\t')
- {
- auto keyEnd = findNextSeparator(aTsvPalette, blockStateEnd + 1);
- if ((keyEnd == AString::npos) || (aTsvPalette[keyEnd] != '\t'))
- {
- throw LoadFailedException(Printf("Incomplete data on line %u (blockState key)", line));
- }
- auto valueEnd = findNextSeparator(aTsvPalette, keyEnd + 1);
- if (valueEnd == AString::npos)
- {
- throw LoadFailedException(Printf("Incomplete data on line %u (blockState value)", line));
- }
- auto key = aTsvPalette.substr(blockStateEnd + 1, keyEnd - blockStateEnd - 1);
- auto value = aTsvPalette.substr(keyEnd + 1, valueEnd - keyEnd - 1);
- blockState[key] = value;
- blockStateEnd = valueEnd;
- }
- addMapping(id, commonPrefix + blockTypeName, std::move(blockState));
- ++line;
- if (aTsvPalette[blockStateEnd] == '\r') // CR of the CRLF pair, skip the LF:
- {
- ++blockStateEnd;
- }
- idx = blockStateEnd;
- }
-}
-
-
-
-
-
-void BlockTypePalette::addMapping(UInt32 aID, const AString & aBlockTypeName, const BlockState & aBlockState)
-{
- mNumberToBlock[aID] = {aBlockTypeName, aBlockState};
- mBlockToNumber[aBlockTypeName][aBlockState] = aID;
- if (aID > mMaxIndex)
- {
- mMaxIndex = aID;
- }
-}