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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ compile_commands.json
/assets
/build-ninja-codex/vcpkg_installed
/build-ninja-codex

/protobuf

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid ignoring the entire /protobuf source directory

Line 130 currently ignores /protobuf wholesale. That can accidentally exclude .proto schema sources from git, which can break reproducibility for CI and other developers. Prefer ignoring only generated outputs (e.g., specific *.pb.* files or build-output paths) instead of the whole directory.

Suggested `.gitignore` adjustment
-/protobuf
+# Keep source .proto files tracked; ignore only generated artifacts (adjust paths as needed)
+/protobuf/**/*.pb.cc
+/protobuf/**/*.pb.h
+/protobuf/**/generated/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/protobuf
# Keep source .proto files tracked; ignore only generated artifacts (adjust paths as needed)
/protobuf/**/*.pb.cc
/protobuf/**/*.pb.h
/protobuf/**/generated/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore at line 130, Do not ignore the entire /protobuf folder; update
.gitignore to stop excluding the source schema files by removing or replacing
the "/protobuf" entry and instead add patterns that only ignore generated
artifacts (for example patterns matching generated protobuf outputs like
"*.pb.go", "*.pb.cc", "*.pb.h", "*.pb.swift", or build/output subdirectories
under protobuf). Locate the "/protobuf" entry in .gitignore and change it to
explicit generated-file patterns or output paths so .proto sources remain
tracked.

24 changes: 23 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ else()
endif()

find_package(OpenGL REQUIRED)
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf REQUIRED)
find_package(LibLZMA REQUIRED)
Comment thread
coderabbitai[bot] marked this conversation as resolved.


if(WIN32)
Expand Down Expand Up @@ -70,8 +73,12 @@ if(NOT nanovg_FOUND)
endif()

include(source/CMakeLists.txt)

set(RME_APPEARANCES_PROTO "${CMAKE_CURRENT_SOURCE_DIR}/source/protobuf/appearances.proto")
protobuf_generate_cpp(RME_PROTO_SRCS RME_PROTO_HDRS "${RME_APPEARANCES_PROTO}")

# Removed WIN32 to enable Console subsystem for persistent debugging logs
add_executable(rme ${rme_H} ${rme_SRC})
add_executable(rme ${rme_H} ${rme_SRC} ${RME_PROTO_SRCS} ${RME_PROTO_HDRS})

set_target_properties(rme PROPERTIES CXX_STANDARD 23)
set_target_properties(rme PROPERTIES CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -100,6 +107,9 @@ target_include_directories(rme PRIVATE
${Boost_INCLUDE_DIRS}
${OPENGL_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${Protobuf_INCLUDE_DIRS}
${LIBLZMA_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}
${LUA_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/source
)
Expand All @@ -118,6 +128,18 @@ else()
target_link_libraries(rme PRIVATE ${ZLIB_LIBRARIES})
endif()

if(TARGET protobuf::libprotobuf)
target_link_libraries(rme PRIVATE protobuf::libprotobuf)
else()
target_link_libraries(rme PRIVATE ${Protobuf_LIBRARIES})
endif()

if(TARGET LibLZMA::LibLZMA)
target_link_libraries(rme PRIVATE LibLZMA::LibLZMA)
else()
target_link_libraries(rme PRIVATE ${LIBLZMA_LIBRARIES})
endif()

target_link_libraries(rme PRIVATE ${OPENGL_LIBRARIES})
target_link_libraries(rme PRIVATE glad::glad)
target_link_libraries(rme PRIVATE glm::glm)
Expand Down
54 changes: 36 additions & 18 deletions data/clients.toml
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ version = 830

[[clients]]
configType = 'dat_otb'
datSignature = '493D607A'
datSignature = '467FD7E6'
dataDirectory = '840'
description = 'sample description'
extended = false
Expand All @@ -245,7 +245,7 @@ name = '8.40'
otbId = 12
otbMajor = 3
otbmVersions = [ 3 ]
sprSignature = '493D4E7C'
sprSignature = '467F9E74'
spritesFile = 'Tibia.spr'
transparency = false
version = 840
Expand Down Expand Up @@ -342,10 +342,10 @@ version = 855

[[clients]]
configType = 'dat_otb'
datSignature = '4C2C7993'
datSignature = '4C28B721'
dataDirectory = '860'
description = 'sample description'
extended = true
extended = false
frameDurations = false
frameGroups = false
metadataFile = 'Tibia.dat'
Expand Down Expand Up @@ -1115,20 +1115,20 @@ transparency = true
version = 1310

[[clients]]
configType = 'dat_otb'
configType = 'protobuf'
datSignature = '4A10'
dataDirectory = '1320'
dataDirectory = 'canary'
description = 'sample description'
extended = true
frameDurations = true
frameGroups = true
metadataFile = 'Tibia.dat'
name = '13.20'
metadataFile = 'appearances-ec29a245e364f190682aa3677ca04f657cb9a2076eca5fc931d039bab8c32887.dat'
name = 'canary2'
otbId = 66
otbMajor = 3
otbmVersions = [ 3 ]
otbmVersions = [ 5, 6 ]
sprSignature = '59E48E02'
spritesFile = 'Tibia.spr'
spritesFile = 'assets/catalog-content.json'
transparency = true
version = 1320

Expand Down Expand Up @@ -1187,20 +1187,20 @@ transparency = false
version = 77

[[clients]]
configType = 'dat_only'
datSignature = '42A3'
configType = 'protobuf'
datSignature = '0'
dataDirectory = 'canary'
description = 'sample description'
extended = true
frameDurations = true
frameGroups = true
metadataFile = 'Tibia.dat'
name = '10.98dat'
metadataFile = 'appearances-eb398f6272e1a0bf9e09c8a5754dbdb28017ef303fc3a0859a6b230640d91c9b.dat'
name = 'canary'
otbId = 57
otbMajor = 3
otbmVersions = [ 3 ]
sprSignature = '57BBD603'
spritesFile = 'Tibia.spr'
otbmVersions = [ 5, 6 ]
sprSignature = '0'
spritesFile = 'assets/catalog-content.json'
transparency = false
version = 1098

Expand All @@ -1219,5 +1219,23 @@ otbMajor = 3
otbmVersions = [ 3 ]
sprSignature = '57BBD603'
spritesFile = 'Tibia.spr'
transparency = true
version = 1098

[[clients]]
configType = 'dat_otb'
datSignature = '0'
dataDirectory = '1287'
description = ''
extended = false
frameDurations = false
frameGroups = false
metadataFile = 'Tibia.dat'
name = 'New Client'
otbId = 0
otbMajor = 1
otbmVersions = []
sprSignature = '0'
spritesFile = 'Tibia.spr'
transparency = false
version = 1098
version = 0
Comment on lines +1225 to +1241

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

New client entry appears to be a template/placeholder.

The new client 'New Client' has version = 0, empty otbmVersions = [], zeroed signatures, and an empty description. This looks like an incomplete template entry that may have been added accidentally.

Consider removing this entry or completing the configuration if it's intended for a specific client version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data/clients.toml` around lines 1225 - 1241, The TOML contains a placeholder
client block with name 'New Client', configType 'dat_otb', version = 0, empty
otbmVersions = [], zeroed signatures (datSignature/sprSignature = '0') and no
description; remove this entire [[clients]] entry or replace it with a completed
configuration for the intended client (populate version, otbmVersions,
signatures, description, and proper file names) so the client list no longer
contains an incomplete template.

1 change: 1 addition & 0 deletions data/menubar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
<item name="Creature" hotkey="C" action="SELECT_CREATURE" help="Select the Creature palette."/>
<item name="Waypoint" hotkey="W" action="SELECT_WAYPOINT" help="Select the Waypoint palette."/>
<item name="RAW" hotkey="R" action="SELECT_RAW" help="Select the RAW palette."/>
<item name="Zone" hotkey="Z" action="SELECT_ZONE" help="Select the Zone palette."/>
</menu>
<menu name="Toolbars">
<item name="Brushes" action="VIEW_TOOLBARS_BRUSHES" help="Show or hide the Brushes toolbar."/>
Expand Down
12 changes: 12 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/brushes/house/house_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/house/house_exit_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/raw/raw_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/spawn/npc_spawn_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/spawn/spawn_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/table/table_border_calculator.h
${CMAKE_CURRENT_LIST_DIR}/brushes/table/table_brush.h
Expand All @@ -53,6 +54,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/brushes/wall/wall_brush_items.h
${CMAKE_CURRENT_LIST_DIR}/brushes/wall/wall_brush_loader.h
${CMAKE_CURRENT_LIST_DIR}/brushes/waypoint/waypoint_brush.h
${CMAKE_CURRENT_LIST_DIR}/brushes/zone/zone_brush.h
${CMAKE_CURRENT_LIST_DIR}/editor/action.h
${CMAKE_CURRENT_LIST_DIR}/editor/action_queue.h
${CMAKE_CURRENT_LIST_DIR}/editor/copybuffer.h
Expand Down Expand Up @@ -102,6 +104,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/dat/dat_item_parser.h
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/otb/otb_item_format.h
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/otb/otb_item_parser.h
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/protobuf/protobuf_item_parser.h
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/xml/xml_item_parser.h

${CMAKE_CURRENT_LIST_DIR}/ingame_preview/floor_visibility_calculator.h
Expand All @@ -117,6 +120,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/io/iomap.h
${CMAKE_CURRENT_LIST_DIR}/io/iomap_otbm.h
${CMAKE_CURRENT_LIST_DIR}/io/map_xml_io.h
${CMAKE_CURRENT_LIST_DIR}/io/xml_file_loader.h
${CMAKE_CURRENT_LIST_DIR}/io/otbm/item_serialization_otbm.h
${CMAKE_CURRENT_LIST_DIR}/io/otbm/header_serialization_otbm.h
${CMAKE_CURRENT_LIST_DIR}/io/otbm/waypoint_serialization_otbm.h
Expand Down Expand Up @@ -152,6 +156,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/palette/palette_common.h
${CMAKE_CURRENT_LIST_DIR}/palette/palette_creature.h
${CMAKE_CURRENT_LIST_DIR}/palette/palette_waypoints.h
${CMAKE_CURRENT_LIST_DIR}/palette/palette_zone.h
${CMAKE_CURRENT_LIST_DIR}/palette/house/house_palette.h
${CMAKE_CURRENT_LIST_DIR}/palette/house/edit_house_dialog.h
${CMAKE_CURRENT_LIST_DIR}/palette/palette_window.h
Expand Down Expand Up @@ -274,6 +279,7 @@ set(rme_H
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/door_property_panel.h
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/spawn_property_panel.h
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/creature_property_panel.h
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/zone_property_panel.h
${CMAKE_CURRENT_LIST_DIR}/ui/dat_debug_view.h
${CMAKE_CURRENT_LIST_DIR}/ui/dcbutton.h
${CMAKE_CURRENT_LIST_DIR}/ui/dialog_helper.h
Expand Down Expand Up @@ -433,6 +439,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/brushes/house/house_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/house/house_exit_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/raw/raw_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/spawn/npc_spawn_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/spawn/spawn_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/table/table_border_calculator.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/table/table_brush.cpp
Expand All @@ -445,6 +452,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/brushes/wall/wall_brush_loader.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/wall/wall_brush_arrays.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/waypoint/waypoint_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/brushes/zone/zone_brush.cpp
${CMAKE_CURRENT_LIST_DIR}/editor/action.cpp
${CMAKE_CURRENT_LIST_DIR}/editor/action_queue.cpp
${CMAKE_CURRENT_LIST_DIR}/editor/copybuffer.cpp
Expand Down Expand Up @@ -482,6 +490,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/item_definitions/core/item_definitions_loader.cpp
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/dat/dat_item_parser.cpp
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/otb/otb_item_parser.cpp
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/protobuf/protobuf_item_parser.cpp
${CMAKE_CURRENT_LIST_DIR}/item_definitions/formats/xml/xml_item_parser.cpp

${CMAKE_CURRENT_LIST_DIR}/ingame_preview/floor_visibility_calculator.cpp
Expand All @@ -497,6 +506,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/io/iomap.cpp
${CMAKE_CURRENT_LIST_DIR}/io/iomap_otbm.cpp
${CMAKE_CURRENT_LIST_DIR}/io/map_xml_io.cpp
${CMAKE_CURRENT_LIST_DIR}/io/xml_file_loader.cpp
${CMAKE_CURRENT_LIST_DIR}/io/otbm/item_serialization_otbm.cpp
${CMAKE_CURRENT_LIST_DIR}/io/otbm/header_serialization_otbm.cpp
${CMAKE_CURRENT_LIST_DIR}/io/otbm/waypoint_serialization_otbm.cpp
Expand Down Expand Up @@ -528,6 +538,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/palette/palette_common.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/palette_creature.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/palette_waypoints.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/palette_zone.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/house/house_palette.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/house/edit_house_dialog.cpp
${CMAKE_CURRENT_LIST_DIR}/palette/palette_window.cpp
Expand Down Expand Up @@ -650,6 +661,7 @@ set(rme_SRC
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/door_property_panel.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/spawn_property_panel.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/creature_property_panel.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/tile_properties/zone_property_panel.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/dat_debug_view.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/dcbutton.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/dialog_helper.cpp
Expand Down
54 changes: 54 additions & 0 deletions source/app/client_asset_detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <algorithm>
#include <array>
#include <format>
#include <fstream>
#include <optional>
#include <span>
#include <string_view>
Expand All @@ -14,6 +15,7 @@
#include "io/filehandle.h"
#include "item_definitions/core/item_definition_fragments.h"
#include "item_definitions/formats/dat/dat_item_parser.h"
#include "util/json.h"

namespace {
constexpr size_t kMaxSampleOffsets = 24;
Expand Down Expand Up @@ -316,6 +318,58 @@ ClientAssetDetectionResult ClientAssetDetector::detect(const ClientVersion& clie
return result;
}

if (client.getItemDefinitionMode() == ItemDefinitionMode::Protobuf) {
const wxFileName package_path(client_path.GetFullPath(), "package.json");
const wxFileName catalog_path(client_path.GetFullPath() + FileName::GetPathSeparator() + "assets", "catalog-content.json");

if (!package_path.FileExists()) {
result.warnings.emplace_back("Client asset detection failed: package.json was not found in the selected protobuf client root.");
return result;
}
if (!catalog_path.FileExists()) {
result.warnings.emplace_back("Client asset detection failed: assets/catalog-content.json was not found in the selected protobuf client root.");
return result;
}

std::ifstream catalog_stream(catalog_path.GetFullPath().ToStdString(), std::ios::in | std::ios::binary);
if (!catalog_stream.is_open()) {
result.warnings.emplace_back("Client asset detection failed: catalog-content.json could not be opened.");
return result;
}

json::json catalog = json::json::parse(catalog_stream, nullptr, false);
if (catalog.is_discarded() || !catalog.is_array()) {
result.warnings.emplace_back("Client asset detection failed: catalog-content.json is invalid.");
return result;
}

for (const auto& entry : catalog) {
if (!entry.is_object()) {
continue;
}
if (entry.value("type", std::string {}) == "appearances") {
const auto filename = entry.value("file", std::string {});
const wxFileName metadata_path(catalog_path.GetPath(), wxString::FromUTF8(filename));
if (!filename.empty() && metadata_path.FileExists()) {
result.metadata_file_name = filename;
break;
}
}
}

if (!result.metadata_file_name.has_value()) {
result.warnings.emplace_back("Client asset detection failed: no appearances entry was found in catalog-content.json.");
return result;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

result.sprites_file_name = "assets/catalog-content.json";
result.transparency = true;
result.extended = true;
result.frame_durations = true;
result.frame_groups = true;
return result;
}

const auto dat_file = resolveClientFile(client_path, client.getMetadataFile(), std::string { ASSETS_NAME } + ".dat");
const auto spr_file = resolveClientFile(client_path, client.getSpritesFile(), std::string { ASSETS_NAME } + ".spr");

Expand Down
Loading
Loading