Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/bedrock/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.15)
project(bedrock LANGUAGES CXX)

add_subdirectory(symbol_generator)
add_subdirectory(signature_generator)

find_package(base64 REQUIRED)
find_package(Boost REQUIRED)
Expand Down Expand Up @@ -134,12 +134,11 @@ add_library(bedrock STATIC
world/scores/server_scoreboard.cpp
)
add_library(bedrock::bedrock ALIAS bedrock)
add_dependencies(bedrock bedrock_symbols)
target_include_directories(bedrock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../)
target_compile_definitions(bedrock PUBLIC ENTT_SPARSE_PAGE=2048)
target_compile_definitions(bedrock PUBLIC ENTT_PACKED_PAGE=128)
target_compile_definitions(bedrock PUBLIC ENTT_NO_MIXIN)
target_link_libraries(bedrock PUBLIC bedrock::symbols endstone::endstone aklomp::base64 boost::boost fmt::fmt EnTT::EnTT glm::glm magic_enum::magic_enum Microsoft.GSL::GSL nonstd::expected-lite)
target_link_libraries(bedrock PUBLIC bedrock::signatures endstone::endstone aklomp::base64 boost::boost fmt::fmt EnTT::EnTT glm::glm magic_enum::magic_enum Microsoft.GSL::GSL nonstd::expected-lite)
if (MSVC)
target_link_options(bedrock PRIVATE /DEBUG /INCREMENTAL:NO /OPT:REF /OPT:ICF)
target_compile_options(bedrock PRIVATE /O2 /DNDEBUG /Zi /Gy)
Expand Down
19 changes: 19 additions & 0 deletions src/bedrock/signature_generator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.15)
project(signature_generator LANGUAGES CXX)

find_package(tomlplusplus CONFIG REQUIRED)

add_executable(signature_generator main.cpp)

target_link_libraries(signature_generator PRIVATE tomlplusplus::tomlplusplus)

add_custom_target(generate_signatures ALL
COMMAND signature_generator ${CMAKE_CURRENT_SOURCE_DIR}/signatures.toml ${CMAKE_BINARY_DIR}/generated/bedrock_signatures.generated.h
DEPENDS signature_generator
COMMENT "Generating bedrock_signatures.generated.h from signatures.toml"
)

add_library(bedrock_signatures INTERFACE)
add_library(bedrock::signatures ALIAS bedrock_signatures)
add_dependencies(bedrock_signatures generate_signatures)
target_include_directories(bedrock_signatures INTERFACE ${CMAKE_BINARY_DIR}/generated)
102 changes: 102 additions & 0 deletions src/bedrock/signature_generator/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>

#include <toml++/toml.h>

namespace {
int generate_include_file(const std::string &output_file, const toml::table &table)
{
namespace fs = std::filesystem;

fs::path output_path = output_file;
fs::path parent_dir = output_path.parent_path();

if (!parent_dir.empty() && !fs::exists(parent_dir)) {
try {
fs::create_directories(parent_dir);
} catch (const fs::filesystem_error &e) {
std::cerr << "Failed to create directories for output file: " << e.what() << '\n';
return 1;
}
}

std::ofstream output(output_file);
if (!output.is_open()) {
std::cerr << "Failed to open output file: " << output_file << '\n';
return 1;
}

output << "#pragma once\n\n";
output << "#include <array>\n#include <string_view>\n\n";
output << "struct SignatureItem {\n";
output << " std::string_view name;\n";
output << " bool relative;\n";
output << " bool rip_relative;\n";
output << " int rip_offset;\n";
output << " int extra;\n";
output << " std::string_view pattern;\n";
output << "};\n\n";

auto *arr = table["signatures"].as_array();
if (!arr) {
std::cerr << "Missing [signatures] array" << '\n';
return 1;
}

output << "static constexpr std::array<SignatureItem, " << arr->size() << "> signatures = {{\n";
for (const auto &elem : *arr) {
auto *sig = elem.as_table();
if (!sig) continue;

auto name = sig->operator[]("name").value<std::string>().value_or("");
auto pattern = sig->operator[]("pattern").value<std::string>().value_or("");
auto relative = sig->operator[]("relative").value<bool>().value_or(false);
auto rip_relative = sig->operator[]("rip_relative").value<bool>().value_or(false);
auto rip_offset = static_cast<int>(sig->operator[]("rip_offset").value<int64_t>().value_or(0));
auto extra = static_cast<int>(sig->operator[]("extra").value<int64_t>().value_or(0));

if (name.empty() || pattern.empty()) {
std::cerr << "Skipping invalid signature entry (missing name/pattern)" << '\n';
continue;
}
output << " { \"" << name << "\", " << (relative ? "true" : "false") << ", "
<< (rip_relative ? "true" : "false") << ", " << rip_offset << ", " << extra << ", \"" << pattern
<< "\" },\n";
}
output << "}};\n";
output.close();
return 0;
}
} // namespace

int main(int argc, char **argv)
{
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <input.toml> <output.h>" << '\n';
return 1;
}

std::string input_file = argv[1];
std::string output_file = argv[2];

try {
auto table = toml::parse_file(input_file);
#ifdef _WIN32
auto *plat = table["windows"].as_table();
#elif __linux__
auto *plat = table["linux"].as_table();
#else
#error Unsupported platform
#endif
if (!plat) {
std::cerr << "Missing platform section in signatures.toml" << '\n';
return 1;
}
return generate_include_file(output_file, *plat);
} catch (const toml::parse_error &err) {
std::cerr << "Failed to parse TOML file: " << err.description() << '\n';
return 1;
}
}
Loading
Loading