From 107fa9944a99b3a27e7e04e41fcccb675b1e17eb Mon Sep 17 00:00:00 2001 From: neoapps-dev Date: Sun, 3 May 2026 11:47:36 +0300 Subject: [PATCH] feat: ItemNameMap fix: ItemNameMap regex fix(cmake): custom target fix(cmake): regex again, add support for Tile.h fix(cmake): deps fix(cmake): windows oh man fix(cmake): windows, again --- CMakeLists.txt | 28 +++++++++++ Minecraft.Client/PlayerConnection.cpp | 13 +++-- cmake/GenerateItemNameMap.cmake | 69 +++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 cmake/GenerateItemNameMap.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a8257ae..5623ed4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,6 +234,34 @@ if(TARGET Minecraft.Server) add_dependencies(Minecraft.Server GenerateStringIdLookup) endif() +set(_item_map_inputs + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Tile.h" + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Item.h" +) + +#neo: added ItemNameMap generation +add_custom_command( + OUTPUT "${CMAKE_BINARY_DIR}/generated/ItemNameMap.h" + COMMAND ${CMAKE_COMMAND} + "-DINPUT_FILES=${_item_map_inputs}" + "-DOUTPUT_FILE=${CMAKE_BINARY_DIR}/generated/ItemNameMap.h" + -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateItemNameMap.cmake" + DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Tile.h" + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/Item.h" + COMMENT "Generating ItemNameMap.h" +) + +add_custom_target(GenerateItemNameMap ALL + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated/ItemNameMap.h" +) + +add_dependencies(Minecraft.Client GenerateItemNameMap) +add_dependencies(Minecraft.World GenerateItemNameMap) +if(PLATFORM_NAME STREQUAL "Windows64") + add_dependencies(Minecraft.Server GenerateItemNameMap) +endif() + target_include_directories(Minecraft.Client PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated" ) diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index b298ea30..18c6f784 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -59,6 +59,9 @@ extern bool g_Win64DedicatedServer; #endif +//neo: added +#include "../Minecraft.World/ItemNameMap.h" + namespace { // Anti-cheat thresholds. Keep server-side checks authoritative even in host mode. @@ -1135,7 +1138,7 @@ void PlayerConnection::handleCommand(const wstring& message) wstring targetName, itemStr, amountStr, auxStr; ss >> targetName >> itemStr >> amountStr >> auxStr; if (targetName.empty() || itemStr.empty()) { - warn(L"Usage: /give [amount] [data]"); + warn(L"Usage: /give |minecraft: [amount] [data]"); return; } @@ -1144,14 +1147,14 @@ void PlayerConnection::handleCommand(const wstring& message) warn(L"Player not found: " + targetName); return; } - - int item, amount = 1, aux = 0; + int item = 0; + int amount = 1, aux = 0; try { - item = std::stoi(itemStr); + item = itemStr.find(L"minecraft:") == 0 ? GetItemIdByName(itemStr.substr(10)) : std::stoi(itemStr); if (!amountStr.empty()) amount = std::stoi(amountStr); if (!auxStr.empty()) aux = std::stoi(auxStr); } catch (...) { - warn(L"Invalid item ID or amount"); + warn(L"Invalid item ID/Name or amount"); return; } diff --git a/cmake/GenerateItemNameMap.cmake b/cmake/GenerateItemNameMap.cmake new file mode 100644 index 00000000..dfcf853e --- /dev/null +++ b/cmake/GenerateItemNameMap.cmake @@ -0,0 +1,69 @@ +if(NOT INPUT_FILES) + message(FATAL_ERROR "INPUT_FILES must be set.") +endif() + +if(NOT OUTPUT_FILE) + message(FATAL_ERROR "OUTPUT_FILE must be set.") +endif() + +set(_entries "") + +foreach(_file IN LISTS INPUT_FILES) + if(NOT EXISTS "${_file}") + message(FATAL_ERROR "Input file does not exist: ${_file}") + endif() + + file(READ "${_file}" _raw) + string(REPLACE "\r\n" "\n" _raw "${_raw}") + string(REPLACE "\r" "\n" _raw "${_raw}") + string(REPLACE "\n" ";" _lines "${_raw}") + + foreach(_line IN LISTS _lines) + if(_line MATCHES "static const int ([A-Za-z_][A-Za-z0-9_]*_Id)[ \t]*=[ \t]*([0-9]+)") + set(_var "${CMAKE_MATCH_1}") + set(_id "${CMAKE_MATCH_2}") + string(REGEX REPLACE "_Id$" "" _name "${_var}") + if(_entries) + string(APPEND _entries ",\n { \"${_name}\", ${_id} }") + else() + set(_entries " { \"${_name}\", ${_id} }") + endif() + endif() + endforeach() +endforeach() + +set(_tmp "${OUTPUT_FILE}.tmp") +file(WRITE "${_tmp}" +"#pragma once\n" +"\n" +"#include \n" +"#include \n" +"\n" +"inline const std::unordered_map g_ItemNameMap =\n" +"{\n" +"${_entries}\n" +"};\n" +"\n" +"inline int GetItemIdByName(const std::string& name)\n" +"{\n" +" auto it = g_ItemNameMap.find(name);\n" +" return (it != g_ItemNameMap.end()) ? it->second : -1;\n" +"}\n" +) + +if(EXISTS "${OUTPUT_FILE}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E compare_files "${OUTPUT_FILE}" "${_tmp}" + RESULT_VARIABLE _changed + ) +else() + set(_changed 1) +endif() + +if(_changed) + file(RENAME "${_tmp}" "${OUTPUT_FILE}") + message(STATUS "GenerateItemNameMap: wrote ${OUTPUT_FILE}") +else() + file(REMOVE "${_tmp}") + message(STATUS "GenerateItemNameMap: ${OUTPUT_FILE} is up-to-date") +endif() \ No newline at end of file