Skip to content

Commit

Permalink
feat: add snbt base64 support
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Oct 6, 2023
1 parent 7bf74f2 commit 3695c44
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ inline size_t getEncodeLength(size_t len) { return (len + 2 - ((len + 2) % 3)) /
inline size_t getEncodeLength(std::string const& str) { return getEncodeLength(str.length()); }

inline size_t getDecodeLength(std::string const& in) {
uint8_t count = 0;
size_t input_size = in.rfind('='); // remove padding size
while (input_size % 4) { // redo padding
unsigned char count = 0;
size_t input_size = in.size();
for (auto it = in.rbegin(); *it == '='; ++it) { ++count; }
input_size -= count; // remove padding size
count = 0; // reset padding counter
while (input_size % 4) { // redo padding
input_size++;
count++;
}
Expand Down
30 changes: 12 additions & 18 deletions src/liteloader/test/TestNbt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ LL_AUTO_TYPED_INSTANCE_HOOK(
}
};

nbt["some"]["new"]["compound"] = nbt;
nbt["hello"]["world"]["\u123456"] = StringTag{R"(\n\t\r\b\u1234\uffffffff)"};
nbt["some"]["new"]["compound"] = nbt;
nbt["hello"]["789\xDB\xFE"]["\u123456"] = StringTag{std::string{R"(\n\t\r\b\u1234\uffffffff)"} + "\xDB\xFE"};


auto nbt2 = *CompoundTag::fromSnbt(R"(
Expand All @@ -56,8 +56,8 @@ LL_AUTO_TYPED_INSTANCE_HOOK(
"long": 10000l
},
"hello": {
"world": {
"\u123456": "\\n\\t\\r\\b\\u1234\\uffffffff"
"Nzg52/4=" /*BASE64*/: {
"ሴ56": "XG5cdFxyXGJcdTEyMzRcdWZmZmZmZmZm2/4=" /*BASE64*/ // hellow
}
},
"intarray": [I;1, 2, 3, 4, 5, -2, -3, -6],
Expand All @@ -68,7 +68,7 @@ LL_AUTO_TYPED_INSTANCE_HOOK(
"new": {
"compound": {
"byte": 127b,
"bytearray": [B;1b, 2b, 3b, 4b, 5b, -2b, -3b, -6b],
"bytearray": [B;1b, 2b, 3b, 4b, 5b, -2b, -3b, -6b], // orld /**/ /* 34t */
"compound": {
"double": 0.3,
"float": 0.1f,
Expand All @@ -90,7 +90,13 @@ LL_AUTO_TYPED_INSTANCE_HOOK(

ll::logger.info("\n{}", nbt.toSnbt(SnbtFormat::PrettyConsolePrint));

ll::logger.info("\n{}", nbt2.toSnbt(SnbtFormat::PrettyConsolePrint));
ll::logger.info("\n{}", nbt2.toSnbt(SnbtFormat::Colored | SnbtFormat::Console));

ll::logger.info(
"\n{}",
((StringTag*)(Tag::parseSnbt(StringTag{nbt2.toNetworkNBT()}.toSnbt()).get()))
->toSnbt(SnbtFormat::PrettyConsolePrint | SnbtFormat::ForceAscii)
);

ll::logger.info("\n{}", nbt.equals(nbt2));

Expand All @@ -100,18 +106,6 @@ LL_AUTO_TYPED_INSTANCE_HOOK(

ll::logger.info("\n{}", nbt.toNetworkNBT() == nbt2.toNetworkNBT());

ll::logger.info("\n{}", StringTag{nbt.toBinaryNBT()}.toSnbt(SnbtFormat::PrettyConsolePrint));
ll::logger.info("\n{}", StringTag{nbt2.toBinaryNBT()}.toSnbt(SnbtFormat::PrettyConsolePrint));

ll::logger.info("\n{}", StringTag{nbt.toNetworkNBT()}.toSnbt(SnbtFormat::PrettyConsolePrint));
ll::logger.info("\n{}", StringTag{nbt2.toNetworkNBT()}.toSnbt(SnbtFormat::PrettyConsolePrint));

ll::logger.info(
"\n{}",
((StringTag*)(Tag::parseSnbt(StringTag{nbt2.toNetworkNBT()}.toSnbt()).get()))
->toSnbt(SnbtFormat::PrettyConsolePrint | SnbtFormat::ForceAscii)
);

ll::logger.info("\n{}", nbt.toNetworkNBT() == nbt.toNetworkNBT());

ll::logger.info("\n{}", nbt.toBinaryNBT() == nbt.toBinaryNBT());
Expand Down
54 changes: 18 additions & 36 deletions src/mc/nbt/SnbtDumpImpl.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "liteloader/api/LoggerAPI.h"
#include "liteloader/api/utils/Base64.h"
#include "liteloader/api/utils/StringUtils.h"
#include "mc/common/ColorFormat.h"
#include "mc/deps/core/mce/Color.h"
Expand All @@ -9,6 +10,8 @@ using namespace ll::StringUtils;

namespace cf = ColorFormat;

static constexpr auto base64Id = std::string{" /*BASE64*/"};

template <typename T>
std::string getString(T&& value) {
return std::format("{}", value);
Expand All @@ -20,52 +23,31 @@ std::string toDumpString(std::string const& str, fmt::color defaultc, std::strin

std::string res;

if (!((int)format & (int)SnbtFormat::UnuseSlashU)) {
nlohmann::json temp{str};
bool base64 = false;

if ((int)format & (int)SnbtFormat::ForceAscii) {
res = temp.dump(-1, ' ', true, nlohmann::json::error_handler_t::ignore);
} else {
try {
res = temp.dump();
} catch (...) { res = temp.dump(-1, ' ', true, nlohmann::json::error_handler_t::ignore); }
}
try {
res = nlohmann::json{str}.dump(
-1,
' ',
(bool)((int)format & (int)SnbtFormat::ForceAscii),
nlohmann::json::error_handler_t::strict
);
res = res.substr(1, res.size() - 2);
} else {
res = str;

std::function strColor = [](std::string const& s) -> std::string { return s; };

if ((int)format & (int)SnbtFormat::Colored) {
if ((int)format & (int)SnbtFormat::Console) {
strColor = [&defaultc](std::string const& s) -> std::string {
return applyTextStyle(fmt::fg(fmt::color::gold), s)
+ applyTextStyle(fmt::fg(defaultc), std::string(""), false);
};
} else {
strColor = [&defaultmc](std::string const& s) -> std::string {
return WrapColorCode(s, cf::MINECOIN_GOLD) + defaultmc;
};
}
}

res = replaceAll(res, "\\", strColor("\\\\"));
res = replaceAll(res, "\b", strColor("\\b"));
res = replaceAll(res, "\f", strColor("\\f"));
res = replaceAll(res, "\n", strColor("\\n"));
res = replaceAll(res, "\r", strColor("\\r"));
res = replaceAll(res, "\t", strColor("\\t"));
res = replaceAll(res, "\v", strColor("\\v"));
res = replaceAll(res, "\"", strColor("\\\""));
res = "\"" + res + "\"";
} catch (...) {
base64 = true;
res = "\"" + ll::base64::Encode(str) + "\"";
}

if ((int)format & (int)SnbtFormat::Colored) {
if ((int)format & (int)SnbtFormat::Console) {
res = applyTextStyle(fmt::fg(defaultc), res);
if (base64) { res += applyTextStyle(fmt::fg(fmt::color::olive_drab), base64Id); }
} else {
res = WrapColorCode(res, defaultmc);
if (base64) { res += WrapColorCode(base64Id, cf::MATERIAL_EMERALD); }
}
} else {
if (base64) { res += base64Id; }
}
return res;
}
Expand Down
11 changes: 10 additions & 1 deletion src/mc/nbt/SnbtParseImpl.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "liteloader/api/utils/Base64.h"
#include "mc/nbt/CompoundTag.h"

std::optional<CompoundTagVariant> parseSnbtValue(std::string_view& s);
Expand Down Expand Up @@ -194,7 +195,15 @@ std::optional<std::string> parseString(std::string_view& s) {

// closing quote
case '\"': {
if (starts == '\"') { return std::string{res.begin(), res.end()}; }
if (starts == '\"') {
auto ans = std::string{res.begin(), res.end()};

if (s.starts_with(" /*BASE64*/")) {
return ll::base64::Decode(ans);
}

return ans;
}
res.push_back('\"');
} break;
case '\'': {
Expand Down
3 changes: 1 addition & 2 deletions src/mc/nbt/Tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ enum class SnbtFormat {
ListNewLine = 1 << 1,
Colored = 1 << 2,
Console = 1 << 3,
UnuseSlashU = 1 << 4,
ForceAscii = 1 << 5,
ForceAscii = 1 << 4,
PartialNewLine = CompoundNewLine,
AlwaysNewLine = CompoundNewLine | ListNewLine,
PrettyFilePrint = CompoundNewLine,
Expand Down
15 changes: 14 additions & 1 deletion src/mc/server/commands/CommandFlag.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ enum class CommandFlagValue : ushort {
Removed = Hidden | HiddenFromAutomationOrigin,
};

[[nodiscard]] constexpr CommandFlagValue operator|(const CommandFlagValue l, const CommandFlagValue r) noexcept {
return static_cast<CommandFlagValue>(
static_cast<std::underlying_type_t<CommandFlagValue>>(l)
| static_cast<std::underlying_type_t<CommandFlagValue>>(r)
);
}
[[nodiscard]] constexpr CommandFlagValue operator&(const CommandFlagValue l, const CommandFlagValue r) noexcept {
return static_cast<CommandFlagValue>(
static_cast<std::underlying_type_t<CommandFlagValue>>(l)
& static_cast<std::underlying_type_t<CommandFlagValue>>(r)
);
}

struct CommandFlag {
public:
enum class CommandFlagValue value;
Expand All @@ -36,7 +49,7 @@ struct CommandFlag {
constexpr bool operator==(CommandFlag const& rhs) const noexcept { return value == rhs.value; }
constexpr bool operator!=(CommandFlag const& rhs) const noexcept { return value != rhs.value; }
CommandFlag& operator|=(CommandFlag const& rhs) {
value = (CommandFlagValue)((ushort)rhs.value | (ushort)value);
value = rhs.value | value;
return *this;
}
};
6 changes: 3 additions & 3 deletions src/mc/server/commands/CommandRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,10 +695,10 @@ class CommandRegistry {
// ?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z
MCAPI void registerCommand(
std::string const& name,
char const* description,
char const* description,
::CommandPermissionLevel,
struct CommandFlag = {CommandFlagValue::NotCheat},
struct CommandFlag = {CommandFlagValue::None}
struct CommandFlag = {CommandFlagValue::None},
struct CommandFlag = {CommandFlagValue::None} // useless, idiot
);

// symbol:
Expand Down

0 comments on commit 3695c44

Please sign in to comment.