diff --git a/UE4SS/include/ExceptionHandling.hpp b/UE4SS/include/ExceptionHandling.hpp index c6745b158..c5aac229a 100644 --- a/UE4SS/include/ExceptionHandling.hpp +++ b/UE4SS/include/ExceptionHandling.hpp @@ -8,7 +8,7 @@ #define UE4SS_ERROR_OUTPUTTER() \ if (!Output::has_internal_error()) \ { \ - Output::send(STR("Error: {}\n"), to_wstring(e.what())); \ + Output::send(STR("Error: {}\n"), ensure_str(e.what())); \ } \ else \ { \ diff --git a/UE4SS/include/GUI/Console.hpp b/UE4SS/include/GUI/Console.hpp index 3800578e5..ead147815 100644 --- a/UE4SS/include/GUI/Console.hpp +++ b/UE4SS/include/GUI/Console.hpp @@ -44,6 +44,6 @@ namespace RC::GUI auto render() -> void; auto render_search_box() -> void; auto add_line(const std::string&, Color::Color) -> void; - auto add_line(const std::wstring&, Color::Color) -> void; + auto add_line(const StringType&, Color::Color) -> void; }; } // namespace RC::GUI diff --git a/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp b/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp index 3f2f6ce4a..f6f6f7c04 100644 --- a/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp @@ -16,7 +16,7 @@ namespace RC::GUI::Filter { for (const auto& property : list_properties) { - if (!property.empty() && !object->GetPropertyByNameInChain(property.c_str())) return true; + if (!property.empty() && !object->GetPropertyByNameInChain(FromCharTypePtr(property.c_str()))) return true; } return false; } diff --git a/UE4SS/include/LuaLibrary.hpp b/UE4SS/include/LuaLibrary.hpp index 709b40cef..2442b3c2a 100644 --- a/UE4SS/include/LuaLibrary.hpp +++ b/UE4SS/include/LuaLibrary.hpp @@ -3,6 +3,8 @@ #include #include +#include + #define DefaultStructMemberData(member_name) \ union { \ const char* as_string{}; \ diff --git a/UE4SS/include/LuaType/LuaCustomProperty.hpp b/UE4SS/include/LuaType/LuaCustomProperty.hpp index b19edc7e2..308f319eb 100644 --- a/UE4SS/include/LuaType/LuaCustomProperty.hpp +++ b/UE4SS/include/LuaType/LuaCustomProperty.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace RC::Unreal { class UObject; @@ -17,11 +19,11 @@ namespace RC::LuaType class LuaCustomProperty { public: - std::wstring m_name{}; + StringType m_name{}; std::unique_ptr m_property; public: - LuaCustomProperty(std::wstring name, std::unique_ptr property); + LuaCustomProperty(StringType name, std::unique_ptr property); private: class PropertyList @@ -30,9 +32,9 @@ namespace RC::LuaType std::vector properties; public: - auto add(std::wstring property_name, std::unique_ptr) -> void; + auto add(StringType property_name, std::unique_ptr) -> void; auto clear() -> void; - auto find_or_nullptr(Unreal::UObject* base, std::wstring property_name) -> Unreal::FProperty*; + auto find_or_nullptr(Unreal::UObject* base, StringType property_name) -> Unreal::FProperty*; }; public: diff --git a/UE4SS/include/LuaType/LuaUObject.hpp b/UE4SS/include/LuaType/LuaUObject.hpp index e5e9f62b4..f7b49a012 100644 --- a/UE4SS/include/LuaType/LuaUObject.hpp +++ b/UE4SS/include/LuaType/LuaUObject.hpp @@ -462,7 +462,7 @@ namespace RC::LuaType { lua.throw_error("Function 'GetProperty' requires a string as the first parameter"); } - std::wstring property_name = to_wstring(lua.get_string(2)); + auto property_name = ensure_str(lua.get_string(2)); auto reflection_table = lua.get_table(); const auto& reflected_object = reflection_table.get_userdata_field("ReflectedObject").get_remote_cpp_object(); @@ -586,7 +586,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. { lua.throw_error(error_overload_not_found); } - auto cmd = to_wstring(lua.get_string()); + auto cmd = ensure_str(lua.get_string()); if (lua.get_stack_size() < 2) { @@ -601,7 +601,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. auto executor = lua.get_userdata(); auto ar = Unreal::FOutputDevice{}; - auto return_value = lua_object.get_remote_cpp_object()->ProcessConsoleExec(cmd.c_str(), ar, executor.get_remote_cpp_object()); + auto return_value = lua_object.get_remote_cpp_object()->ProcessConsoleExec(FromCharTypePtr(cmd.c_str()), ar, executor.get_remote_cpp_object()); lua.set_bool(return_value); return 1; @@ -641,7 +641,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. { auto& lua_object = lua.get_userdata(); - const std::wstring& member_name = to_const_wstring(lua.get_string()); + const StringType& member_name = ensure_str_const(lua.get_string()); // If nullptr then we assume the UObject wasn't found so lets return an invalid UObject to Lua // This allows the safe chaining of "__index" as long as the Lua script checks ":IsValid()" before using the object @@ -777,7 +777,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. { // We can either throw an error and kill the execution /**/ - std::wstring property_type_name = property_type.ToString(); + StringType property_type_name = property_type.ToString(); lua.throw_error(fmt::format( "[LocalUnrealParam::prepare_to_handle] Tried accessing unreal property without a registered handler. Property type '{}' not supported.", to_string(property_type_name))); diff --git a/UE4SS/include/Mod/CppMod.hpp b/UE4SS/include/Mod/CppMod.hpp index 5f89acc9f..0406c2272 100644 --- a/UE4SS/include/Mod/CppMod.hpp +++ b/UE4SS/include/Mod/CppMod.hpp @@ -7,6 +7,8 @@ #include #include +#include + namespace RC { namespace LuaMadeSimple @@ -21,7 +23,7 @@ namespace RC typedef void (*uninstall_type)(CppUserModBase*); private: - std::wstring m_dlls_path; + std::filesystem::path m_dlls_path; Unreal::Windows::HMODULE m_main_dll_module = NULL; void* m_dlls_path_cookie = NULL; @@ -31,7 +33,7 @@ namespace RC CppUserModBase* m_mod = nullptr; public: - CppMod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + CppMod(UE4SSProgram&, StringType&& mod_name, StringType&& mod_path); CppMod(CppMod&) = delete; CppMod(CppMod&&) = delete; ~CppMod() override; @@ -62,6 +64,6 @@ namespace RC auto fire_ui_init() -> void override; auto fire_program_start() -> void override; auto fire_update() -> void override; - auto fire_dll_load(std::wstring_view dll_name) -> void; + auto fire_dll_load(StringViewType dll_name) -> void; }; } // namespace RC diff --git a/UE4SS/include/Mod/CppUserModBase.hpp b/UE4SS/include/Mod/CppUserModBase.hpp index 710f17210..414a2321e 100644 --- a/UE4SS/include/Mod/CppUserModBase.hpp +++ b/UE4SS/include/Mod/CppUserModBase.hpp @@ -8,6 +8,8 @@ #include #include +#include + namespace RC { struct ModMetadata @@ -125,14 +127,14 @@ namespace RC { } - RC_UE4SS_API virtual auto on_dll_load(std::wstring_view dll_name) -> void + RC_UE4SS_API virtual auto on_dll_load(StringViewType dll_name) -> void { } RC_UE4SS_API virtual auto render_tab() -> void{}; protected: - RC_UE4SS_API auto register_tab(std::wstring_view tab_name, GUI::GUITab::RenderFunctionType) -> void; + RC_UE4SS_API auto register_tab(StringViewType tab_name, GUI::GUITab::RenderFunctionType) -> void; RC_UE4SS_API auto register_keydown_event(Input::Key, const Input::EventCallbackCallable&, uint8_t custom_data = 0) -> void; RC_UE4SS_API auto register_keydown_event(Input::Key, const Input::Handler::ModifierKeyArray&, const Input::EventCallbackCallable&, uint8_t custom_data = 0) -> void; diff --git a/UE4SS/include/Mod/LuaMod.hpp b/UE4SS/include/Mod/LuaMod.hpp index 31ad8435c..77f97eb50 100644 --- a/UE4SS/include/Mod/LuaMod.hpp +++ b/UE4SS/include/Mod/LuaMod.hpp @@ -6,12 +6,15 @@ #include #include #include +#include #include #include #include #include +#include + namespace RC { class UE4SSProgram; @@ -26,7 +29,7 @@ namespace RC class LuaMod : public Mod { private: - std::wstring m_scripts_path; + std::filesystem::path m_scripts_path; LuaMadeSimple::Lua& m_lua; public: @@ -124,7 +127,7 @@ namespace RC std::mutex m_actions_lock{}; public: - LuaMod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + LuaMod(UE4SSProgram&, StringType&& mod_name, StringType&& mod_path); ~LuaMod() override = default; private: diff --git a/UE4SS/include/Mod/Mod.hpp b/UE4SS/include/Mod/Mod.hpp index 3cdcbbb6b..c68dbd5b4 100644 --- a/UE4SS/include/Mod/Mod.hpp +++ b/UE4SS/include/Mod/Mod.hpp @@ -25,8 +25,10 @@ namespace RC UE4SSProgram& m_program; protected: - std::wstring m_mod_name; - std::wstring m_mod_path; +#pragma warning(disable : 4251) + StringType m_mod_name; + std::filesystem::path m_mod_path; +#pragma warning(default : 4251) protected: // Whether the mod can be installed @@ -43,11 +45,11 @@ namespace RC }; public: - Mod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + Mod(UE4SSProgram&, StringType&& mod_name, std::filesystem::path&& mod_path); virtual ~Mod() = default; public: - auto get_name() const -> std::wstring_view; + auto get_name() const -> StringViewType; virtual auto start_mod() -> void = 0; virtual auto uninstall() -> void = 0; diff --git a/UE4SS/include/ObjectDumper/ObjectToString.hpp b/UE4SS/include/ObjectDumper/ObjectToString.hpp index 0b0525a2b..dbe716502 100644 --- a/UE4SS/include/ObjectDumper/ObjectToString.hpp +++ b/UE4SS/include/ObjectDumper/ObjectToString.hpp @@ -5,10 +5,12 @@ #include +#include + namespace RC::ObjectDumper { using ToStringHash = size_t; - using ObjectToStringDecl = std::function; + using ObjectToStringDecl = std::function; extern std::unordered_map object_to_string_functions; using ObjectToStringComplexDeclCallable = const std::function&; @@ -20,33 +22,33 @@ namespace RC::ObjectDumper auto to_string_exists(size_t hash) -> bool; auto to_string_complex_exists(size_t hash) -> bool; - auto object_trivial_dump_to_string(void* p_this, std::wstring& out_line, const wchar_t* post_delimiter = L".") -> void; - auto object_to_string(void* p_this, std::wstring& out_line) -> void; + auto object_trivial_dump_to_string(void* p_this, StringType& out_line, const CharType* post_delimiter = STR(".")) -> void; + auto object_to_string(void* p_this, StringType& out_line) -> void; - auto property_trivial_dump_to_string(void* p_this, std::wstring& out_line) -> void; - auto property_to_string(void* p_this, std::wstring& out_line) -> void; + auto property_trivial_dump_to_string(void* p_this, StringType& out_line) -> void; + auto property_to_string(void* p_this, StringType& out_line) -> void; - auto arrayproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto arrayproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto arrayproperty_to_string(void* p_this, StringType& out_line) -> void; + auto arrayproperty_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; - auto mapproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto mapproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto mapproperty_to_string(void* p_this, StringType& out_line) -> void; + auto mapproperty_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; - auto classproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto delegateproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto fieldpathproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto interfaceproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto multicastdelegateproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto objectproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto structproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto enumproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto boolproperty_to_string(void* p_this, std::wstring& out_line) -> void; + auto classproperty_to_string(void* p_this, StringType& out_line) -> void; + auto delegateproperty_to_string(void* p_this, StringType& out_line) -> void; + auto fieldpathproperty_to_string(void* p_this, StringType& out_line) -> void; + auto interfaceproperty_to_string(void* p_this, StringType& out_line) -> void; + auto multicastdelegateproperty_to_string(void* p_this, StringType& out_line) -> void; + auto objectproperty_to_string(void* p_this, StringType& out_line) -> void; + auto structproperty_to_string(void* p_this, StringType& out_line) -> void; + auto enumproperty_to_string(void* p_this, StringType& out_line) -> void; + auto boolproperty_to_string(void* p_this, StringType& out_line) -> void; - auto enum_to_string(void* p_this, std::wstring& out_line) -> void; - auto struct_to_string(void* p_this, std::wstring& out_line) -> void; - auto function_to_string(void* p_this, std::wstring& out_line) -> void; + auto enum_to_string(void* p_this, StringType& out_line) -> void; + auto struct_to_string(void* p_this, StringType& out_line) -> void; + auto function_to_string(void* p_this, StringType& out_line) -> void; - auto scriptstruct_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto scriptstruct_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; auto init() -> void; } // namespace RC::ObjectDumper diff --git a/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp b/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp index 59cf49670..1fc0c3ddb 100644 --- a/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp +++ b/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp @@ -8,10 +8,13 @@ #include #include +#include #pragma warning(disable : 4005) #include #pragma warning(default : 4005) +#include + namespace RC::Unreal { class UObject; @@ -65,14 +68,14 @@ namespace RC::UEGenerator struct PropertyTypeDeclarationContext { - std::wstring context_name; + StringType context_name; class GeneratedSourceFile* source_file; bool is_top_level_declaration; bool* out_is_bitmask_bool; - PropertyTypeDeclarationContext(const std::wstring& context_name, + PropertyTypeDeclarationContext(const StringType& context_name, GeneratedSourceFile* source_file = NULL, bool is_top_level_declaration = false, bool* out_is_bitmask_bool = NULL) @@ -91,21 +94,21 @@ namespace RC::UEGenerator struct StringInsensitiveCompare { - auto operator()(const std::wstring& a, const std::wstring& b) const -> bool + auto operator()(const StringType& a, const StringType& b) const -> bool { - return _wcsicmp(a.c_str(), b.c_str()) < 0; + return Unreal::FGenericPlatformStricmp::Stricmp(a.c_str(), b.c_str()) < 0; } }; - using CaseInsensitiveSet = std::set; + using CaseInsensitiveSet = std::set; class GeneratedFile { protected: - std::wstring m_file_base_name; + StringType m_file_base_name; FFilePath m_full_file_path; - std::wstring m_file_contents_buffer; + StringType m_file_contents_buffer; int32_t m_current_indent_count; public: @@ -117,34 +120,34 @@ namespace RC::UEGenerator GeneratedFile(GeneratedFile&&) = default; auto operator=(const GeneratedFile&) -> void = delete; - auto append_line(const std::wstring& line) -> void; - auto append_line_no_indent(const std::wstring& line) -> void; + auto append_line(const StringType& line) -> void; + auto append_line_no_indent(const StringType& line) -> void; auto begin_indent_level() -> void; auto end_indent_level() -> void; auto serialize_file_content_to_disk() -> bool; virtual auto has_content_to_save() const -> bool; - virtual auto generate_file_contents() -> std::wstring; + virtual auto generate_file_contents() -> StringType; }; class GeneratedSourceFile : public GeneratedFile { private: - std::wstring m_file_module_name; + StringType m_file_module_name; std::map m_dependencies; - std::set m_extra_includes; - mutable std::set m_dependency_module_names; + std::set m_extra_includes; + mutable std::set m_dependency_module_names; UObject* m_object; GeneratedSourceFile* m_header_file; bool m_is_implementation_file; bool m_needs_get_type_hash; public: - std::wstring m_implementation_constructor; + StringType m_implementation_constructor; std::unordered_set parent_property_names{}; std::map> attachments{}; - GeneratedSourceFile(const FFilePath& file_path, const std::wstring& file_module_name, bool is_implementation_file, UObject* object); + GeneratedSourceFile(const FFilePath& file_path, const StringType& file_module_name, bool is_implementation_file, UObject* object); // Delete copy and move constructors and assignment operator GeneratedSourceFile(const GeneratedSourceFile&) = delete; @@ -153,9 +156,9 @@ namespace RC::UEGenerator auto set_header_file(GeneratedSourceFile* header_file) -> void; auto add_dependency_object(UObject* object, DependencyLevel dependency_level) -> void; - auto add_extra_include(const std::wstring& included_file_name) -> void; + auto add_extra_include(const StringType& included_file_name) -> void; - auto get_header_module_name() const -> const std::wstring& + auto get_header_module_name() const -> const StringType& { return m_file_module_name; } @@ -179,23 +182,23 @@ namespace RC::UEGenerator virtual auto has_content_to_save() const -> bool override; - auto copy_dependency_module_names(std::set& out_dependency_module_names) const -> void + auto copy_dependency_module_names(std::set& out_dependency_module_names) const -> void { out_dependency_module_names.insert(m_dependency_module_names.begin(), m_dependency_module_names.end()); } auto static create_source_file(const FFilePath& root_dir, - const std::wstring& module_name, - const std::wstring& base_name, + const StringType& module_name, + const StringType& base_name, bool is_implementation_file, UObject* object) -> GeneratedSourceFile; - virtual auto generate_file_contents() -> std::wstring override; + virtual auto generate_file_contents() -> StringType override; protected: auto has_dependency(UObject* object, DependencyLevel dependency_level) -> bool; - auto generate_pre_declarations_string() const -> std::wstring; - auto generate_includes_string() const -> std::wstring; + auto generate_pre_declarations_string() const -> StringType; + auto generate_includes_string() const -> StringType; }; struct UniqueName @@ -210,16 +213,16 @@ namespace RC::UEGenerator { private: FFilePath m_root_directory; - std::wstring m_primary_module_name; + StringType m_primary_module_name; - std::set m_forced_module_dependencies; - std::set m_ignored_module_names; - std::set m_classes_with_object_initializer; + std::set m_forced_module_dependencies; + std::set m_ignored_module_names; + std::set m_classes_with_object_initializer; - std::unordered_map m_underlying_enum_types; - std::set m_blueprint_visible_enums; - std::set m_blueprint_visible_structs; - std::map>> m_module_dependencies; + std::unordered_map m_underlying_enum_types; + std::set m_blueprint_visible_enums; + std::set m_blueprint_visible_structs; + std::map>> m_module_dependencies; std::vector m_header_files; std::unordered_set m_structs_that_need_get_type_hash; @@ -229,7 +232,7 @@ namespace RC::UEGenerator static std::map m_dependency_object_to_unique_id; // Storage for class defaultsubojects when populating property initializers - std::unordered_map m_class_subobjects; + std::unordered_map m_class_subobjects; public: UEHeaderGenerator(const FFilePath& root_directory); @@ -243,8 +246,8 @@ namespace RC::UEGenerator auto dump_native_packages() -> void; auto generate_object_description_file(UObject* object) -> bool; - auto generate_module_build_file(const std::wstring& module_name) -> void; - auto generate_module_implementation_file(const std::wstring& module_name) -> void; + auto generate_module_build_file(const StringType& module_name) -> void; + auto generate_module_implementation_file(const StringType& module_name) -> void; private: auto generate_interface_definition(UClass* function, GeneratedSourceFile& header_data) -> void; @@ -264,7 +267,7 @@ namespace RC::UEGenerator const CaseInsensitiveSet& blacklisted_property_names, bool generate_as_override = false) -> void; - auto generate_property_value(UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const std::wstring& property_scope) + auto generate_property_value(UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const StringType& property_scope) -> void; auto generate_function_implementation(UClass* uclass, UFunction* function, @@ -272,49 +275,49 @@ namespace RC::UEGenerator bool is_generating_interface, const CaseInsensitiveSet& blacklisted_property_names) -> void; - auto generate_interface_flags(UClass* uinterface) const -> std::wstring; - auto generate_class_flags(UClass* uclass) const -> std::wstring; - auto generate_struct_flags(UScriptStruct* script_struct) const -> std::wstring; - auto generate_enum_flags(UEnum* uenum) const -> std::wstring; - auto generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> std::wstring; - auto generate_property_flags(FProperty* property) const -> std::wstring; - auto generate_function_argument_flags(FProperty* property) const -> std::wstring; - auto generate_function_flags(UFunction* function, bool is_function_pure_virtual = false) const -> std::wstring; + auto generate_interface_flags(UClass* uinterface) const -> StringType; + auto generate_class_flags(UClass* uclass) const -> StringType; + auto generate_struct_flags(UScriptStruct* script_struct) const -> StringType; + auto generate_enum_flags(UEnum* uenum) const -> StringType; + auto generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> StringType; + auto generate_property_flags(FProperty* property) const -> StringType; + auto generate_function_argument_flags(FProperty* property) const -> StringType; + auto generate_function_flags(UFunction* function, bool is_function_pure_virtual = false) const -> StringType; auto generate_function_parameter_list(UClass* property, UFunction* function, GeneratedSourceFile& header_data, bool generate_comma_before_name, - const std::wstring& context_name, + const StringType& context_name, const CaseInsensitiveSet& blacklisted_property_names, - int32_t* out_num_params = NULL) -> std::wstring; - auto generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const std::wstring& ContextName) -> std::wstring; + int32_t* out_num_params = NULL) -> StringType; + auto generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const StringType& ContextName) -> StringType; - auto generate_enum_value(UEnum* uenum, int64_t enum_value) -> std::wstring; + auto generate_enum_value(UEnum* uenum, int64_t enum_value) -> StringType; auto generate_simple_assignment_expression(FProperty* property, - const std::wstring& value, + const StringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& operator_type = STR(" = ")) -> void; + const StringType& property_scope, + const StringType& operator_type = STR(" = ")) -> void; auto generate_advanced_assignment_expression(FProperty* property, - const std::wstring& value, + const StringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& property_type, - const std::wstring& operator_type = STR(" = ")) -> void; + const StringType& property_scope, + const StringType& property_type, + const StringType& operator_type = STR(" = ")) -> void; - auto static generate_parameter_count_string(int32_t parameter_count) -> std::wstring; - auto static determine_primary_game_module_name() -> std::wstring; + auto static generate_parameter_count_string(int32_t parameter_count) -> StringType; + auto static determine_primary_game_module_name() -> StringType; public: - auto add_module_and_sub_module_dependencies(std::set& out_module_dependencies, const std::wstring& module_name, bool add_self_module = true) + auto add_module_and_sub_module_dependencies(std::set& out_module_dependencies, const StringType& module_name, bool add_self_module = true) -> void; auto static collect_blacklisted_property_names(UObject* property) -> CaseInsensitiveSet; - auto static generate_object_pre_declaration(UObject* object) -> std::vector>; + auto static generate_object_pre_declaration(UObject* object) -> std::vector>; - auto static convert_module_name_to_api_name(const std::wstring& module_name) -> std::wstring; - auto static get_module_name_for_package(UObject* package) -> std::wstring; - auto static sanitize_enumeration_name(const std::wstring& enumeration_name) -> std::wstring; + auto static convert_module_name_to_api_name(const StringType& module_name) -> StringType; + auto static get_module_name_for_package(UObject* package) -> StringType; + auto static sanitize_enumeration_name(const StringType& enumeration_name) -> StringType; auto static get_highest_enum(UEnum* uenum) -> int64_t; auto static get_lowest_enum(UEnum* uenum) -> int64_t; @@ -325,8 +328,8 @@ namespace RC::UEGenerator auto static append_access_modifier(GeneratedSourceFile& header_data, AccessModifier needed_access, AccessModifier& current_access) -> void; auto static get_property_access_modifier(FProperty* property) -> AccessModifier; auto static get_function_access_modifier(UFunction* function) -> AccessModifier; - auto static create_string_literal(const std::wstring& string) -> std::wstring; - auto static get_header_name_for_object(UObject* object, bool get_existing_header = false) -> std::wstring; - auto static generate_cross_module_include(UObject* object, const std::wstring& module_name, const std::wstring& fallback_name) -> std::wstring; + auto static create_string_literal(const StringType& string) -> StringType; + auto static get_header_name_for_object(UObject* object, bool get_existing_header = false) -> StringType; + auto static generate_cross_module_include(UObject* object, const StringType& module_name, const StringType& fallback_name) -> StringType; }; } // namespace RC::UEGenerator diff --git a/UE4SS/include/Signatures.hpp b/UE4SS/include/Signatures.hpp index f2951bc79..1e0a30c75 100644 --- a/UE4SS/include/Signatures.hpp +++ b/UE4SS/include/Signatures.hpp @@ -2,6 +2,8 @@ #include +#include + namespace RC::Unreal::UnrealInitializer { struct Config; @@ -21,7 +23,7 @@ namespace RC using LuaScriptMatchFoundFunc = const std::function; using LuaScriptScanCompleteFunc = const std::function; - auto scan_from_lua_script(std::wstring& script_file_path_and_name, + auto scan_from_lua_script(std::filesystem::path& script_file_path_and_name, std::vector&, LuaScriptMatchFoundFunc& match_found_func, LuaScriptScanCompleteFunc& scan_complete_func = &scan_complete_default_func) -> void; diff --git a/UE4SS/include/UE4SSProgram.hpp b/UE4SS/include/UE4SSProgram.hpp index e542f7e52..d91b705f1 100644 --- a/UE4SS/include/UE4SSProgram.hpp +++ b/UE4SS/include/UE4SSProgram.hpp @@ -21,6 +21,8 @@ #include #include +#include + // Used to set up ImGui context and allocator in DLL mods #define UE4SS_ENABLE_IMGUI() \ /* Wait for UE4SS to create the imgui context. */ \ @@ -84,9 +86,9 @@ namespace RC friend class CppUserModBase; // m_input_handler public: - constexpr static wchar_t m_settings_file_name[] = L"UE4SS-settings.ini"; - constexpr static wchar_t m_log_file_name[] = L"UE4SS.log"; - constexpr static wchar_t m_object_dumper_file_name[] = L"UE4SS_ObjectDump.txt"; + constexpr static CharType m_settings_file_name[] = STR("UE4SS-settings.ini"); + constexpr static CharType m_log_file_name[] = STR("UE4SS.log"); + constexpr static CharType m_object_dumper_file_name[] = STR("UE4SS_ObjectDump.txt"); public: RC_UE4SS_API static SettingsManager settings_manager; @@ -168,13 +170,13 @@ namespace RC }; public: - UE4SSProgram(const std::wstring& ModuleFilePath, std::initializer_list options); + UE4SSProgram(const std::filesystem::path& ModuleFilePath, std::initializer_list options); ~UE4SSProgram(); UE4SSProgram(const UE4SSProgram&) = delete; UE4SSProgram(UE4SSProgram&&) = delete; private: - auto setup_paths(const std::wstring& moduleFilePath) -> void; + auto setup_paths(const std::filesystem::path& moduleFilePath) -> void; enum class FunctionStatus { Success, @@ -204,18 +206,18 @@ namespace RC auto fire_unreal_init_for_cpp_mods() -> void; auto fire_ui_init_for_cpp_mods() -> void; auto fire_program_start_for_cpp_mods() -> void; - auto fire_dll_load_for_cpp_mods(std::wstring_view dll_name) -> void; + auto fire_dll_load_for_cpp_mods(StringViewType dll_name) -> void; public: auto init() -> void; auto is_program_started() -> bool; auto reinstall_mods() -> void; auto get_object_dumper_output_directory() -> const File::StringType; - RC_UE4SS_API auto get_module_directory() -> File::StringViewType; - RC_UE4SS_API auto get_game_executable_directory() -> File::StringViewType; - RC_UE4SS_API auto get_working_directory() -> File::StringViewType; - RC_UE4SS_API auto get_mods_directory() -> File::StringViewType; - RC_UE4SS_API auto get_legacy_root_directory() -> File::StringViewType; + RC_UE4SS_API auto get_module_directory() -> File::StringType; + RC_UE4SS_API auto get_game_executable_directory() -> File::StringType; + RC_UE4SS_API auto get_working_directory() -> File::StringType; + RC_UE4SS_API auto get_mods_directory() -> File::StringType; + RC_UE4SS_API auto get_legacy_root_directory() -> File::StringType; RC_UE4SS_API auto generate_uht_compatible_headers() -> void; RC_UE4SS_API auto generate_cxx_headers(const std::filesystem::path& output_dir) -> void; RC_UE4SS_API auto generate_lua_types(const std::filesystem::path& output_dir) -> void; @@ -257,7 +259,7 @@ namespace RC static auto install_lua_mods() -> void; using FMBNI_ExtraPredicate = std::function; - static auto find_mod_by_name_internal(std::wstring_view mod_name, + static auto find_mod_by_name_internal(StringViewType mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No, FMBNI_ExtraPredicate extra_predicate = {}) -> Mod*; @@ -269,7 +271,7 @@ namespace RC RC_UE4SS_API static auto dump_all_objects_and_properties(const File::StringType& output_path_and_file_name) -> void; template - static auto find_mod_by_name(std::wstring_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> T* + static auto find_mod_by_name(StringViewType mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> T* { std::abort(); }; @@ -279,14 +281,14 @@ namespace RC std::abort(); }; template <> - auto find_mod_by_name(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* + auto find_mod_by_name(StringViewType mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* { return static_cast(find_mod_by_name_internal(mod_name, is_installed, is_started, [](auto elem) -> bool { return dynamic_cast(elem); })); } template <> - auto find_mod_by_name(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started) -> CppMod* + auto find_mod_by_name(StringViewType mod_name, IsInstalled is_installed, IsStarted is_started) -> CppMod* { return static_cast(find_mod_by_name_internal(mod_name, is_installed, is_started, [](auto elem) -> bool { return dynamic_cast(elem); @@ -295,15 +297,15 @@ namespace RC template <> auto find_mod_by_name(std::string_view mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* { - return find_mod_by_name(to_wstring(mod_name), is_installed, is_started); + return find_mod_by_name(ensure_str(mod_name), is_installed, is_started); } template <> auto find_mod_by_name(std::string_view mod_name, IsInstalled is_installed, IsStarted is_started) -> CppMod* { - return find_mod_by_name(to_wstring(mod_name), is_installed, is_started); + return find_mod_by_name(ensure_str(mod_name), is_installed, is_started); } - RC_UE4SS_API static auto find_lua_mod_by_name(std::wstring_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> LuaMod*; + RC_UE4SS_API static auto find_lua_mod_by_name(StringViewType mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> LuaMod*; RC_UE4SS_API static auto find_lua_mod_by_name(std::string_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> LuaMod*; static auto static_cleanup() -> void; RC_UE4SS_API static auto get_program() -> UE4SSProgram& diff --git a/UE4SS/proxy_generator/main.cpp b/UE4SS/proxy_generator/main.cpp index 8feee84e8..d350af5e1 100644 --- a/UE4SS/proxy_generator/main.cpp +++ b/UE4SS/proxy_generator/main.cpp @@ -170,15 +170,15 @@ int _tmain(int argc, TCHAR* argv[]) cpp_file << "void load_original_dll()" << endl; cpp_file << "{" << endl; - cpp_file << " File::CharType path[MAX_PATH];" << endl; + cpp_file << " wchar_t path[MAX_PATH];" << endl; cpp_file << " GetSystemDirectory(path, MAX_PATH);" << endl; cpp_file << endl; - cpp_file << std::format(" File::StringType dll_path = File::StringType(path) + STR(\"\\\\{}\");", input_dll_name.string()) << endl; + cpp_file << std::format(" std::wstring dll_path = std::wstring(path) + L\"\\\\{}\";", input_dll_name.string()) << endl; cpp_file << endl; cpp_file << " SOriginalDll = LoadLibrary(dll_path.c_str());" << endl; cpp_file << " if (!SOriginalDll)" << endl; cpp_file << " {" << endl; - cpp_file << " MessageBox(nullptr, STR(\"Failed to load proxy DLL\"), STR(\"UE4SS Error\"), MB_OK | MB_ICONERROR);" << endl; + cpp_file << " MessageBox(nullptr, L\"Failed to load proxy DLL\", L\"UE4SS Error\", MB_OK | MB_ICONERROR);" << endl; cpp_file << " ExitProcess(0);" << endl; cpp_file << " }" << endl; cpp_file << "}" << endl; @@ -230,7 +230,7 @@ int _tmain(int argc, TCHAR* argv[]) cpp_file << " if (!hModule)" << endl; cpp_file << " {" << endl; cpp_file << " // If loading from ue4ss directory fails, load from the current directory" << endl; - cpp_file << " hModule = LoadLibrary(STR(\"UE4SS.dll\"));" << endl; + cpp_file << " hModule = LoadLibrary(L\"UE4SS.dll\");" << endl; cpp_file << " }" << endl; cpp_file << endl; cpp_file << " return hModule;" << endl; @@ -249,7 +249,7 @@ int _tmain(int argc, TCHAR* argv[]) cpp_file << " }" << endl; cpp_file << " else" << endl; cpp_file << " {" << endl; - cpp_file << " MessageBox(nullptr, STR(\"Failed to load UE4SS.dll. Please see the docs on correct installation: https://docs.ue4ss.com/installation-guide\"), STR(\"UE4SS Error\"), MB_OK | MB_ICONERROR);" << endl; + cpp_file << " MessageBox(nullptr, L\"Failed to load UE4SS.dll. Please see the docs on correct installation: https://docs.ue4ss.com/installation-guide\", L\"UE4SS Error\", MB_OK | MB_ICONERROR);" << endl; cpp_file << " ExitProcess(0);" << endl; cpp_file << " }" << endl; cpp_file << " }" << endl; diff --git a/UE4SS/src/CrashDumper.cpp b/UE4SS/src/CrashDumper.cpp index d500eece8..e823ce51a 100644 --- a/UE4SS/src/CrashDumper.cpp +++ b/UE4SS/src/CrashDumper.cpp @@ -9,6 +9,8 @@ #include #include +#include + namespace fs = std::filesystem; using std::chrono::seconds; @@ -25,14 +27,14 @@ namespace RC LONG WINAPI ExceptionHandler(_EXCEPTION_POINTERS* exception_pointers) { const auto now = time_point_cast(system_clock::now()); - const std::wstring dump_path = fmt::format(L"{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp", StringType{UE4SSProgram::get_program().get_working_directory()}, now); + const StringType dump_path = fmt::format(STR("{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp"), StringType{UE4SSProgram::get_program().get_working_directory()}, now); - const HANDLE file = CreateFileW(dump_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + const HANDLE file = CreateFileW(FromCharTypePtr(dump_path.c_str()), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) { - const std::wstring message = fmt::format(L"Failed to create crashdump file, reason: {:x}", GetLastError()); - MessageBoxW(NULL, message.c_str(), L"Fatal Error!", MB_OK); + const StringType message = fmt::format(STR("Failed to create crashdump file, reason: {:x}"), GetLastError()); + MessageBoxW(NULL, FromCharTypePtr(message.c_str()), L"Fatal Error!", MB_OK); return EXCEPTION_CONTINUE_SEARCH; } @@ -53,13 +55,13 @@ namespace RC if (!ok) { - const std::wstring message = fmt::format(L"Failed to write crashdump file, reason: {:x}", GetLastError()); - MessageBoxW(NULL, message.c_str(), L"Fatal Error!", MB_OK); + const StringType message = fmt::format(STR("Failed to write crashdump file, reason: {:x}"), GetLastError()); + MessageBoxW(NULL, FromCharTypePtr(message.c_str()), L"Fatal Error!", MB_OK); return EXCEPTION_CONTINUE_SEARCH; } - const std::wstring message = fmt::format(L"Crashdump written to: {}", dump_path); - MessageBoxW(NULL, message.c_str(), L"Fatal Error!", MB_OK); + const StringType message = fmt::format(STR("Crashdump written to: {}"), dump_path); + MessageBoxW(NULL, FromCharTypePtr(message.c_str()), L"Fatal Error!", MB_OK); return EXCEPTION_EXECUTE_HANDLER; } diff --git a/UE4SS/src/GUI/BPMods.cpp b/UE4SS/src/GUI/BPMods.cpp index 04afce1aa..c982a4497 100644 --- a/UE4SS/src/GUI/BPMods.cpp +++ b/UE4SS/src/GUI/BPMods.cpp @@ -31,7 +31,7 @@ namespace RC::GUI::BPMods public: auto ModMenuButtonPressed(int32_t Index) -> void { - auto Function = GetFunctionByNameInChain(STR("ModMenuButtonPressed")); + auto Function = GetFunctionByNameInChain(FromCharTypePtr(STR("ModMenuButtonPressed"))); if (!Function) { return; @@ -113,7 +113,7 @@ namespace RC::GUI::BPMods const auto& mod_button = mod_info.ModButtons[i2]; if (ImGui::Button(fmt::format("{}", mod_button).c_str())) { - Output::send(STR("Mod button {} hit.\n"), to_wstring(mod_button)); + Output::send(STR("Mod button {} hit.\n"), ensure_str(mod_button)); mod_info.ModActor->ModMenuButtonPressed(static_cast(i2)); } } diff --git a/UE4SS/src/GUI/Console.cpp b/UE4SS/src/GUI/Console.cpp index b0150c9a5..51aafae58 100644 --- a/UE4SS/src/GUI/Console.cpp +++ b/UE4SS/src/GUI/Console.cpp @@ -189,9 +189,9 @@ namespace RC::GUI m_text_editor.AddTextLine(line); } - auto Console::add_line(const std::wstring& line, Color::Color color) -> void + auto Console::add_line(const StringType& line, Color::Color color) -> void { - auto ansi_string = to_string(line); + auto utf8_string = to_string(line); std::lock_guard guard(m_lines_mutex); if (m_text_editor.GetTotalLines() < 0) { @@ -209,7 +209,7 @@ namespace RC::GUI { m_text_editor.GetLineColorMarkers().emplace(m_text_editor.GetTotalLines() + 1, LogLevel_to_ImColor(color)); } - m_lines.emplace_back(ansi_string); - m_text_editor.AddTextLine(ansi_string); + m_lines.emplace_back(utf8_string); + m_text_editor.AddTextLine(utf8_string); } } // namespace RC::GUI diff --git a/UE4SS/src/GUI/Dumpers.cpp b/UE4SS/src/GUI/Dumpers.cpp index 640b1864f..75592d23e 100644 --- a/UE4SS/src/GUI/Dumpers.cpp +++ b/UE4SS/src/GUI/Dumpers.cpp @@ -83,21 +83,21 @@ namespace RC::GUI::Dumpers { StringType root_actor_buffer{}; - static auto location_property = root_component->GetPropertyByNameInChain(STR("RelativeLocation")); - static auto rotation_property = root_component->GetPropertyByNameInChain(STR("RelativeRotation")); - static auto scale_property = root_component->GetPropertyByNameInChain(STR("RelativeScale3D")); + static auto location_property = root_component->GetPropertyByNameInChain(FromCharTypePtr(STR("RelativeLocation"))); + static auto rotation_property = root_component->GetPropertyByNameInChain(FromCharTypePtr(STR("RelativeRotation"))); + static auto scale_property = root_component->GetPropertyByNameInChain(FromCharTypePtr(STR("RelativeScale3D"))); - auto location = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeLocation")); + auto location = root_component->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeLocation"))); FString location_string{}; location_property->ExportTextItem(location_string, location, nullptr, nullptr, 0); root_actor_buffer.append(fmt::format(STR("\"{}\","), location_string.GetCharArray())); - auto rotation = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeRotation")); + auto rotation = root_component->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeRotation"))); FString rotation_string{}; rotation_property->ExportTextItem(rotation_string, rotation, nullptr, nullptr, 0); root_actor_buffer.append(fmt::format(STR("\"{}\","), rotation_string.GetCharArray())); - auto scale = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeScale3D")); + auto scale = root_component->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeScale3D"))); FString scale_string{}; scale_property->ExportTextItem(scale_string, scale, nullptr, nullptr, 0); root_actor_buffer.append(fmt::format(STR("\"{}\","), scale_string.GetCharArray())); @@ -120,7 +120,7 @@ namespace RC::GUI::Dumpers auto actor = static_cast(object); - auto root_component = actor->GetValuePtrByPropertyNameInChain(STR("RootComponent")); + auto root_component = actor->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RootComponent"))); if (!root_component || !*root_component) { return LoopAction::Continue; @@ -131,7 +131,7 @@ namespace RC::GUI::Dumpers actor_buffer.append(fmt::format(STR("Row_{},"), actor_count)); static auto game_mode_base = UObjectGlobals::FindFirstOf(STR("GameModeBase")); - static auto class_property = game_mode_base->GetPropertyByNameInChain(STR("GameStateClass")); + static auto class_property = game_mode_base->GetPropertyByNameInChain(FromCharTypePtr(STR("GameStateClass"))); FString actor_class_string{}; class_property->ExportTextItem(actor_class_string, &actor->GetClassPrivate(), nullptr, nullptr, 0); actor_buffer.append(fmt::format(STR("{},"), actor_class_string.GetCharArray())); @@ -146,7 +146,7 @@ namespace RC::GUI::Dumpers actor_buffer.append(STR("(")); for (auto [static_mesh_component_ptr, static_mesh_component_index] : static_mesh_components | views::enumerate) { - const auto mesh = *static_mesh_component_ptr->GetValuePtrByPropertyNameInChain(STR("StaticMesh")); + const auto mesh = *static_mesh_component_ptr->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("StaticMesh"))); if (!mesh) { Output::send(STR("SKIPPING COMPONENT! StaticMeshComponent '{}' has no mesh.\n"), @@ -154,7 +154,7 @@ namespace RC::GUI::Dumpers continue; } - static auto mesh_property = static_mesh_component_ptr->GetPropertyByNameInChain(STR("StaticMesh")); + static auto mesh_property = static_mesh_component_ptr->GetPropertyByNameInChain(FromCharTypePtr(STR("StaticMesh"))); FString mesh_string{}; mesh_property->ExportTextItem(mesh_string, &mesh, nullptr, nullptr, 0); actor_buffer.append(fmt::format(STR("(StaticMesh={}',"), mesh_string.GetCharArray())); @@ -186,7 +186,7 @@ namespace RC::GUI::Dumpers if (Version::IsAtMost(4, 19)) { - const auto materials = *mesh->GetValuePtrByPropertyName>(STR("StaticMaterials")); + const auto materials = *mesh->GetValuePtrByPropertyName>(FromCharTypePtr(STR("StaticMaterials"))); if (materials.GetData()) { actor_buffer.append(STR("Materials=(")); @@ -206,7 +206,7 @@ namespace RC::GUI::Dumpers } else { - const auto& materials = *mesh->GetValuePtrByPropertyName>(STR("StaticMaterials")); + const auto& materials = *mesh->GetValuePtrByPropertyName>(FromCharTypePtr(STR("StaticMaterials"))); if (materials.GetData()) { actor_buffer.append(STR("Materials=(")); @@ -256,7 +256,7 @@ namespace RC::GUI::Dumpers auto actor = static_cast(object); - auto root_component = actor->GetValuePtrByPropertyNameInChain(STR("RootComponent")); + auto root_component = actor->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RootComponent"))); if (!root_component || !*root_component) { return LoopAction::Continue; @@ -267,7 +267,7 @@ namespace RC::GUI::Dumpers actor_json_object.new_string(STR("Name"), fmt::format(STR("Row_{}"), actor_count)); static auto game_mode_base = UObjectGlobals::FindFirstOf(STR("GameModeBase")); - static auto class_property = game_mode_base->GetPropertyByNameInChain(STR("GameStateClass")); + static auto class_property = game_mode_base->GetPropertyByNameInChain(FromCharTypePtr(STR("GameStateClass"))); FString actor_class_string{}; class_property->ExportTextItem(actor_class_string, &actor->GetClassPrivate(), nullptr, nullptr, 0); actor_json_object.new_string(STR("Actor"), fmt::format(STR("{}"), StringViewType{actor_class_string.GetCharArray()})); @@ -279,19 +279,19 @@ namespace RC::GUI::Dumpers root_component_json_object.new_string(STR("SceneComponentClass"), fmt::format(STR("{}"), StringViewType{root_component_class_string.GetCharArray()})); auto& location_json_object = root_component_json_object.new_object(STR("Location")); - auto location = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeLocation")); + auto location = (*root_component)->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeLocation"))); location_json_object.new_number(STR("X"), location->X()); location_json_object.new_number(STR("Y"), location->Y()); location_json_object.new_number(STR("Z"), location->Z()); auto& rotation_json_object = root_component_json_object.new_object(STR("Rotation")); - auto rotation = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeRotation")); + auto rotation = (*root_component)->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeRotation"))); rotation_json_object.new_number(STR("Pitch"), rotation->GetPitch()); rotation_json_object.new_number(STR("Yaw"), rotation->GetYaw()); rotation_json_object.new_number(STR("Roll"), rotation->GetRoll()); auto& scale_json_object = root_component_json_object.new_object(STR("Scale")); - auto scale = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeScale3D")); + auto scale = (*root_component)->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("RelativeScale3D"))); scale_json_object.new_number(STR("X"), scale->X()); scale_json_object.new_number(STR("Y"), scale->Y()); scale_json_object.new_number(STR("Z"), scale->Z()); @@ -310,7 +310,7 @@ namespace RC::GUI::Dumpers { Output::send(STR("Dumping CSV of all loaded static mesh actors, positions and mesh properties\n")); static auto dump_actor_class = UObjectGlobals::StaticFindObject(nullptr, nullptr, STR("/Script/Engine.StaticMeshActor")); - std::wstring file_buffer{}; + StringType file_buffer{}; file_buffer.append(generate_actors_csv_file(dump_actor_class)); auto file = File::open(fmt::format(STR("{}\\{}-ue4ss_static_mesh_data.csv"), UE4SSProgram::get_program().get_working_directory(), long(std::time(nullptr))), @@ -324,7 +324,7 @@ namespace RC::GUI::Dumpers void call_generate_all_actor_file() { Output::send(STR("Dumping CSV of all loaded actor types, positions and mesh properties\n")); - std::wstring file_buffer{}; + StringType file_buffer{}; file_buffer.append(generate_actors_csv_file(AActor::StaticClass())); auto file = File::open(fmt::format(STR("{}\\{}-ue4ss_actor_data.csv"), UE4SSProgram::get_program().get_working_directory(), long(std::time(nullptr))), File::OpenFor::Writing, diff --git a/UE4SS/src/GUI/GLFW3_OpenGL3.cpp b/UE4SS/src/GUI/GLFW3_OpenGL3.cpp index 24727ba9a..4fda57451 100644 --- a/UE4SS/src/GUI/GLFW3_OpenGL3.cpp +++ b/UE4SS/src/GUI/GLFW3_OpenGL3.cpp @@ -14,7 +14,7 @@ namespace RC::GUI { static void glfw_error_callback(int error, const char* description) { - Output::send(STR("Glfw Error {}: {}\n"), error, to_wstring(description)); + Output::send(STR("Glfw Error {}: {}\n"), error, ensure_str(description)); } auto Backend_GLFW3_OpenGL3::init() -> void diff --git a/UE4SS/src/GUI/GUI.cpp b/UE4SS/src/GUI/GUI.cpp index e770705c0..fd2c3fae1 100644 --- a/UE4SS/src/GUI/GUI.cpp +++ b/UE4SS/src/GUI/GUI.cpp @@ -333,7 +333,7 @@ namespace RC::GUI { if (!Output::has_internal_error()) { - Output::send(STR("Error: {}\n"), to_wstring(e.what())); + Output::send(STR("Error: {}\n"), ensure_str(e.what())); } else { diff --git a/UE4SS/src/GUI/ImGuiUtility.cpp b/UE4SS/src/GUI/ImGuiUtility.cpp index 858516299..d50b53e53 100644 --- a/UE4SS/src/GUI/ImGuiUtility.cpp +++ b/UE4SS/src/GUI/ImGuiUtility.cpp @@ -98,9 +98,9 @@ namespace RC::GUI static auto dump_json_integer_value(const JSON::Number& element) -> void; static int indent_level{}; - static auto indent() -> std::wstring + static auto indent() -> StringType { - std::wstring indents{}; + StringType indents{}; for (int i = 0; i < indent_level; ++i) { indents.append(STR(" ")); diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 92b95b0e3..568d41311 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -625,7 +625,7 @@ namespace RC::GUI LiveView::Watch* watch = [&]() -> LiveView::Watch* { if (watch_type == LiveView::Watch::Type::Property) { - auto property = object->GetPropertyByNameInChain(property_name.data()); + auto property = object->GetPropertyByNameInChain(FromCharTypePtr(property_name.data())); if (!property) { return nullptr; @@ -1577,7 +1577,7 @@ namespace RC::GUI } else { - Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : to_wstring(search_buffer)); + Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : ensure_str(search_buffer)); s_name_to_search_by = search_buffer; m_object_iterator = &LiveView::guobjectarray_by_name_iterator; m_is_searching_by_name = true; @@ -1718,7 +1718,7 @@ namespace RC::GUI { if (ImGui::IsItemClicked()) { - printf_s("Clicked: %S\n", ustruct->GetFullName().c_str()); + printf_s("Clicked: %S\n", FromCharTypePtr(ustruct->GetFullName().c_str())); select_object(0, ustruct->GetObjectItem(), ustruct, AffectsHistory::Yes); } } @@ -2010,7 +2010,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - if (!property->ImportText(to_wstring(m_current_property_value_buffer).c_str(), property->ContainerPtrToValuePtr(container), NULL, obj, &placeholder_device)) + if (!property->ImportText(FromCharTypePtr(ensure_str(m_current_property_value_buffer).c_str()), property->ContainerPtrToValuePtr(container), NULL, obj, &placeholder_device)) { m_modal_edit_property_value_error_unable_to_edit = true; ImGui::OpenPopup("UnableToSetNewPropertyValueError"); @@ -2178,7 +2178,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - StringType new_name = to_wstring(m_current_property_value_buffer); + auto new_name = ensure_str(m_current_property_value_buffer); FName new_key = FName(new_name, FNAME_Add); uenum->EditNameAt(index, new_key); if (uenum->GetEnumNames()[index].Key.ToString() != new_name) @@ -2262,7 +2262,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - StringType new_name = to_wstring(m_current_property_value_buffer); + auto new_name = ensure_str(m_current_property_value_buffer); FName new_key = FName(new_name, FNAME_Add); int64 value = names[index].Value; @@ -3201,7 +3201,7 @@ namespace RC::GUI while (std::getline(ss, class_name, ',')) { std::erase_if(class_name, isspace); - Filter::ClassNamesFilter::list_class_names.emplace_back(to_wstring(class_name)); + Filter::ClassNamesFilter::list_class_names.emplace_back(ensure_str(class_name)); } } } @@ -3218,7 +3218,7 @@ namespace RC::GUI while (std::getline(ss, class_name, ',')) { std::erase_if(class_name, isspace); - Filter::ClassNamesFilter::list_class_names.emplace_back(to_wstring(class_name)); + Filter::ClassNamesFilter::list_class_names.emplace_back(ensure_str(class_name)); } } } @@ -3239,7 +3239,7 @@ namespace RC::GUI while (std::getline(ss, property_name, ',')) { std::erase_if(property_name, isspace); - Filter::HasProperty::list_properties.emplace_back(to_wstring(property_name)); + Filter::HasProperty::list_properties.emplace_back(ensure_str(property_name)); } } } @@ -3262,7 +3262,7 @@ namespace RC::GUI std::erase_if(property_type_name, isspace); if (!property_type_name.empty()) { - Filter::HasPropertyType::list_property_types.emplace_back(FName(to_wstring(property_type_name), FNAME_Add)); + Filter::HasPropertyType::list_property_types.emplace_back(FName(ensure_str(property_type_name), FNAME_Add)); } } } diff --git a/UE4SS/src/GUI/SearcherWidget.cpp b/UE4SS/src/GUI/SearcherWidget.cpp index 2cb338cc8..1b752a7a9 100644 --- a/UE4SS/src/GUI/SearcherWidget.cpp +++ b/UE4SS/src/GUI/SearcherWidget.cpp @@ -63,7 +63,7 @@ namespace RC::GUI } else { - // Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : to_wstring(search_buffer)); + // Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : ensure_str(search_buffer)); m_name_to_search_by = search_buffer; m_current_iterator = m_search_iterator; m_is_searching_by_name = true; diff --git a/UE4SS/src/GUI/UFunctionCallerWidget.cpp b/UE4SS/src/GUI/UFunctionCallerWidget.cpp index 83373fafe..37165c5ef 100644 --- a/UE4SS/src/GUI/UFunctionCallerWidget.cpp +++ b/UE4SS/src/GUI/UFunctionCallerWidget.cpp @@ -151,7 +151,7 @@ namespace RC::GUI auto& function_flags = s_function->GetFunctionFlags(); function_flags |= FUNC_Exec; Output::send(STR("Processing command: {}\n"), s_cmd); - bool call_succeeded = s_instance->ProcessConsoleExec(s_cmd.c_str(), s_ar, s_executor); + bool call_succeeded = s_instance->ProcessConsoleExec(FromCharTypePtr(s_cmd.c_str()), s_ar, s_executor); Output::send(STR("call_succeeded: {}\n"), call_succeeded); function_flags &= ~FUNC_Exec; } @@ -167,7 +167,7 @@ namespace RC::GUI auto cmd = fmt::format(STR("{}"), function->GetName()); for (const auto& param : m_params_for_selected_function) { - cmd.append(fmt::format(STR(" {}"), to_wstring(param.value_from_ui))); + cmd.append(fmt::format(STR(" {}"), ensure_str(param.value_from_ui))); } Output::send(STR("Queueing command: {}\n"), cmd); @@ -250,7 +250,7 @@ namespace RC::GUI if (object_name_type_space_location == object_name.npos) { Output::send(STR("Could not copy name of PlayerController, was unable to find space in full PlayerController name: '{}'."), - to_wstring(object_name)); + ensure_str(object_name)); return {}; } else diff --git a/UE4SS/src/GUI/Windows.cpp b/UE4SS/src/GUI/Windows.cpp index 486654ef4..b46fe658e 100644 --- a/UE4SS/src/GUI/Windows.cpp +++ b/UE4SS/src/GUI/Windows.cpp @@ -55,10 +55,10 @@ namespace RC::GUI // wc.hbrBackground = NULL; s_wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); s_wc.lpszMenuName = NULL; - s_wc.lpszClassName = title_bar_text.c_str(); + s_wc.lpszClassName = FromCharTypePtr(title_bar_text.c_str()); s_wc.hIconSm = NULL; ::RegisterClassEx(&s_wc); - s_hwnd = ::CreateWindow(s_wc.lpszClassName, title_bar_text.c_str(), WS_OVERLAPPEDWINDOW, loc_x, loc_y, size_x, size_y, NULL, NULL, s_wc.hInstance, NULL); + s_hwnd = ::CreateWindow(s_wc.lpszClassName, FromCharTypePtr(title_bar_text.c_str()), WS_OVERLAPPEDWINDOW, loc_x, loc_y, size_x, size_y, NULL, NULL, s_wc.hInstance, NULL); if (!m_gfx_backend->create_device()) { diff --git a/UE4SS/src/LuaLibrary.cpp b/UE4SS/src/LuaLibrary.cpp index 5f24b4112..e388e6675 100644 --- a/UE4SS/src/LuaLibrary.cpp +++ b/UE4SS/src/LuaLibrary.cpp @@ -66,7 +66,7 @@ namespace RC::LuaLibrary Output::send(formatted_string); - if (output_device) output_device->Log(outdevice_string.c_str()); + if (output_device) output_device->Log(FromCharTypePtr(outdevice_string.c_str())); return 0; } @@ -100,7 +100,7 @@ namespace RC::LuaLibrary // Logging will only happen to the debug console but it's something at least if (!Output::has_internal_error()) { - Output::send(STR("Error: {}\n"), to_wstring(e)); + Output::send(STR("Error: {}\n"), ensure_str(e)); } else { @@ -108,31 +108,31 @@ namespace RC::LuaLibrary } } - static auto exported_function_status_to_string(ExportedFunctionStatus status) -> std::wstring_view + static auto exported_function_status_to_string(ExportedFunctionStatus status) -> StringViewType { switch (status) { case ExportedFunctionStatus::NO_ERROR_TO_EXPORT: - return L"NO_ERROR_TO_EXPORT | 0"; + return STR("NO_ERROR_TO_EXPORT | 0"); case ExportedFunctionStatus::UNKNOWN_ERROR: - return L"UNKNOWN_ERROR | 7"; + return STR("UNKNOWN_ERROR | 7"); case ExportedFunctionStatus::SUCCESS: - return L"SUCCESS | 1"; + return STR("SUCCESS | 1"); case ExportedFunctionStatus::VARIABLE_NOT_FOUND: - return L"VARIABLE_NOT_FOUND | 2"; + return STR("VARIABLE_NOT_FOUND | 2"); case ExportedFunctionStatus::MOD_IS_NULLPTR: - return L"MOD_IS_NULLPTR | 3"; + return STR("MOD_IS_NULLPTR | 3"); case ExportedFunctionStatus::SCRIPT_FUNCTION_RETURNED_FALSE: - return L"SCRIPT_FUNCTION_RETURNED_FALSE | 4"; + return STR("SCRIPT_FUNCTION_RETURNED_FALSE | 4"); case ExportedFunctionStatus::UNABLE_TO_CALL_SCRIPT_FUNCTION: - return L"UNABLE_TO_CALL_SCRIPT_FUNCTION | 5"; + return STR("UNABLE_TO_CALL_SCRIPT_FUNCTION | 5"); case ExportedFunctionStatus::SCRIPT_FUNCTION_NOT_FOUND: - return L"SCRIPT_FUNCTION_NOT_FOUND | 6"; + return STR("SCRIPT_FUNCTION_NOT_FOUND | 6"); case ExportedFunctionStatus::UE4SS_NOT_INITIALIZED: - return L"UE4SS_NOT_INITIALIZED | 8"; + return STR("UE4SS_NOT_INITIALIZED | 8"); } - return L"Missed switch case"; + return STR("Missed switch case"); } auto get_lua_state_by_mod_name(const char* mod_name) -> lua_State* diff --git a/UE4SS/src/LuaType/LuaCustomProperty.cpp b/UE4SS/src/LuaType/LuaCustomProperty.cpp index 90b4be840..6d7a7064d 100644 --- a/UE4SS/src/LuaType/LuaCustomProperty.cpp +++ b/UE4SS/src/LuaType/LuaCustomProperty.cpp @@ -12,11 +12,11 @@ namespace RC::LuaType { LuaCustomProperty::PropertyList LuaCustomProperty::StaticStorage::property_list; - LuaCustomProperty::LuaCustomProperty(std::wstring name, std::unique_ptr property) : m_name(name), m_property(std::move(property)) + LuaCustomProperty::LuaCustomProperty(StringType name, std::unique_ptr property) : m_name(name), m_property(std::move(property)) { } - auto LuaCustomProperty::PropertyList::add(std::wstring property_name, std::unique_ptr property) -> void + auto LuaCustomProperty::PropertyList::add(StringType property_name, std::unique_ptr property) -> void { (void)properties.emplace_back(LuaCustomProperty{property_name, std::move(property)}).m_property.get(); } @@ -26,7 +26,7 @@ namespace RC::LuaType properties.clear(); } - auto LuaCustomProperty::PropertyList::find_or_nullptr(Unreal::UObject* base, std::wstring property_name) -> Unreal::FProperty* + auto LuaCustomProperty::PropertyList::find_or_nullptr(Unreal::UObject* base, StringType property_name) -> Unreal::FProperty* { Unreal::FProperty* custom_property_found{}; diff --git a/UE4SS/src/LuaType/LuaFName.cpp b/UE4SS/src/LuaType/LuaFName.cpp index 207ecc3e8..f56074358 100644 --- a/UE4SS/src/LuaType/LuaFName.cpp +++ b/UE4SS/src/LuaType/LuaFName.cpp @@ -64,7 +64,7 @@ No overload found for function 'FName'. Unreal::EFindName find_type{Unreal::EFindName::FNAME_Add}; if (lua.is_string()) { - name_string = to_wstring(lua.get_string()); + name_string = ensure_str(lua.get_string()); } else if (lua.is_integer()) { diff --git a/UE4SS/src/LuaType/LuaFOutputDevice.cpp b/UE4SS/src/LuaType/LuaFOutputDevice.cpp index 105c59ce2..9994c6ed1 100644 --- a/UE4SS/src/LuaType/LuaFOutputDevice.cpp +++ b/UE4SS/src/LuaType/LuaFOutputDevice.cpp @@ -65,7 +65,7 @@ No overload found for function 'Log'. } auto message = lua.get_string(); - lua_object.get_remote_cpp_object()->Log(to_wstring(message).c_str()); + lua_object.get_remote_cpp_object()->Log(FromCharTypePtr(ensure_str(message).c_str())); return 0; }); diff --git a/UE4SS/src/LuaType/LuaFString.cpp b/UE4SS/src/LuaType/LuaFString.cpp index ad412aa01..d9f33e40e 100644 --- a/UE4SS/src/LuaType/LuaFString.cpp +++ b/UE4SS/src/LuaType/LuaFString.cpp @@ -54,7 +54,7 @@ namespace RC::LuaType table.add_pair("ToString", [](const LuaMadeSimple::Lua& lua) -> int { auto& lua_object = lua.get_userdata(); - const wchar_t* string_data = lua_object.get_local_cpp_object().GetCharArray(); + const CharType* string_data = lua_object.get_local_cpp_object().GetCharArray(); if (string_data) { lua.set_string(to_string(string_data)); diff --git a/UE4SS/src/LuaType/LuaFText.cpp b/UE4SS/src/LuaType/LuaFText.cpp index d28a91ef6..b5b3622cd 100644 --- a/UE4SS/src/LuaType/LuaFText.cpp +++ b/UE4SS/src/LuaType/LuaFText.cpp @@ -61,7 +61,7 @@ No overload found for function 'FText'. StringType text_string{}; if (lua.is_string()) { - text_string = to_wstring(lua.get_string()); + text_string = ensure_str(lua.get_string()); } else { diff --git a/UE4SS/src/LuaType/LuaUEnum.cpp b/UE4SS/src/LuaType/LuaUEnum.cpp index f25a8a15d..b3910e13f 100644 --- a/UE4SS/src/LuaType/LuaUEnum.cpp +++ b/UE4SS/src/LuaType/LuaUEnum.cpp @@ -161,7 +161,7 @@ No overload found for function 'UEnum.InsertIntoNames'. // P1 (Name), string if (lua.is_string()) { - param_name = to_wstring(lua.get_string()); + param_name = ensure_str(lua.get_string()); } else { @@ -242,7 +242,7 @@ No overload found for function 'UEnum.EditNameAt'. lua.throw_error("'UEnum.EditNameAt' could not load parameter for \"NewName\""); } - Unreal::FName new_key = Unreal::FName(to_wstring(param_new_name), Unreal::FNAME_Add); + Unreal::FName new_key = Unreal::FName(ensure_str(param_new_name), Unreal::FNAME_Add); lua_object.get_remote_cpp_object()->EditNameAt(param_index, new_key); return 0; diff --git a/UE4SS/src/LuaType/LuaUObject.cpp b/UE4SS/src/LuaType/LuaUObject.cpp index 969d1b753..bbe9cde5e 100644 --- a/UE4SS/src/LuaType/LuaUObject.cpp +++ b/UE4SS/src/LuaType/LuaUObject.cpp @@ -1107,7 +1107,7 @@ namespace RC::LuaType if (params.lua.is_string()) { auto lua_string = params.lua.get_string(); - auto fstring = Unreal::FString{to_wstring(lua_string).c_str()}; + auto fstring = Unreal::FString{FromCharTypePtr(ensure_str(lua_string).c_str())}; *string = fstring; } else if (params.lua.is_userdata()) @@ -1233,7 +1233,7 @@ No overload found for function 'IsA'. } else if (lua.is_string()) { - auto* object_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_wstring(lua.get_string())); + auto* object_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, ensure_str(lua.get_string())); lua.set_bool(is_a_internal(lua, object, object_class)); } else diff --git a/UE4SS/src/LuaType/LuaUScriptStruct.cpp b/UE4SS/src/LuaType/LuaUScriptStruct.cpp index 14ee6cd4e..c541353d4 100644 --- a/UE4SS/src/LuaType/LuaUScriptStruct.cpp +++ b/UE4SS/src/LuaType/LuaUScriptStruct.cpp @@ -196,7 +196,7 @@ namespace RC::LuaType { auto& lua_object = lua.get_userdata(); - Unreal::FName property_name = Unreal::FName(to_wstring(lua.get_string())); + Unreal::FName property_name = Unreal::FName(ensure_str(lua.get_string())); // Check if property_name is 'NONE' if (property_name.GetComparisonIndex() == 0) diff --git a/UE4SS/src/LuaType/LuaXProperty.cpp b/UE4SS/src/LuaType/LuaXProperty.cpp index dc9944626..8a01c90f5 100644 --- a/UE4SS/src/LuaType/LuaXProperty.cpp +++ b/UE4SS/src/LuaType/LuaXProperty.cpp @@ -227,7 +227,7 @@ No overload found for function 'ImportText'. File::StringType buffer; if (lua.is_string()) { - buffer = to_wstring(lua.get_string()); + buffer = ensure_str(lua.get_string()); } else { @@ -261,7 +261,7 @@ No overload found for function 'ImportText'. } auto* owner_object = lua.get_userdata().get_remote_cpp_object(); - lua_object.get_remote_cpp_object()->ImportText(buffer.c_str(), data, port_flags, owner_object, nullptr); + lua_object.get_remote_cpp_object()->ImportText(FromCharTypePtr(buffer.c_str()), data, port_flags, owner_object, nullptr); return 0; }); diff --git a/UE4SS/src/Mod/CppMod.cpp b/UE4SS/src/Mod/CppMod.cpp index 57283bf46..3e46cdeb6 100644 --- a/UE4SS/src/Mod/CppMod.cpp +++ b/UE4SS/src/Mod/CppMod.cpp @@ -10,9 +10,9 @@ namespace RC { - CppMod::CppMod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)) + CppMod::CppMod(UE4SSProgram& program, StringType&& mod_name, StringType&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)) { - m_dlls_path = m_mod_path + L"\\dlls"; + m_dlls_path = m_mod_path / STR("dlls"); if (!std::filesystem::exists(m_dlls_path)) { @@ -21,14 +21,14 @@ namespace RC return; } - auto dll_path = m_dlls_path + L"\\main.dll"; + auto dll_path = m_dlls_path / STR("main.dll"); // Add mods dlls directory to search path for dynamic/shared linked libraries in mods m_dlls_path_cookie = AddDllDirectory(m_dlls_path.c_str()); m_main_dll_module = LoadLibraryExW(dll_path.c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); if (!m_main_dll_module) { - Output::send(STR("Failed to load dll <{}> for mod {}, error code: 0x{:x}\n"), dll_path, m_mod_name, GetLastError()); + Output::send(STR("Failed to load dll <{}> for mod {}, error code: 0x{:x}\n"), ensure_str(dll_path), m_mod_name, GetLastError()); set_installable(false); return; } @@ -60,9 +60,9 @@ namespace RC if (!Output::has_internal_error()) { Output::send(STR("Failed to load dll <{}> for mod {}, because: {}\n"), - m_dlls_path + L"\\main.dll\n", + ensure_str((m_dlls_path / STR("main.dll"))), m_mod_name, - to_wstring(e.what())); + ensure_str(e.what())); } else { @@ -154,7 +154,7 @@ namespace RC } } - auto CppMod::fire_dll_load(std::wstring_view dll_name) -> void + auto CppMod::fire_dll_load(StringViewType dll_name) -> void { if (m_mod) { diff --git a/UE4SS/src/Mod/CppUserModBase.cpp b/UE4SS/src/Mod/CppUserModBase.cpp index ee8dd1a50..26be6a05b 100644 --- a/UE4SS/src/Mod/CppUserModBase.cpp +++ b/UE4SS/src/Mod/CppUserModBase.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace RC { @@ -49,7 +50,7 @@ namespace RC }); } - auto CppUserModBase::register_tab(std::wstring_view tab_name, GUI::GUITab::RenderFunctionType render_function) -> void + auto CppUserModBase::register_tab(StringViewType tab_name, GUI::GUITab::RenderFunctionType render_function) -> void { auto& tab = GUITabs.emplace_back(std::make_shared(tab_name, render_function, this)); UE4SSProgram::get_program().add_gui_tab(tab); diff --git a/UE4SS/src/Mod/LuaMod.cpp b/UE4SS/src/Mod/LuaMod.cpp index 6b290aa06..c0bd7677a 100644 --- a/UE4SS/src/Mod/LuaMod.cpp +++ b/UE4SS/src/Mod/LuaMod.cpp @@ -254,8 +254,8 @@ namespace RC // If the type wasn't supported then we simply clean the Lua stack, output a warning and then do nothing lua_data.lua.discard_value(); - std::wstring parameter_type_name = property_type_name.ToString(); - std::wstring parameter_name = lua_data.return_property->GetName(); + auto parameter_type_name = property_type_name.ToString(); + auto parameter_name = lua_data.return_property->GetName(); Output::send( STR("Tried altering return value of a hooked UFunction without a registered handler for return type Return property '{}' of type " @@ -629,12 +629,12 @@ namespace RC efindname_table.make_global("EFindName"); } - LuaMod::LuaMod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) + LuaMod::LuaMod(UE4SSProgram& program, StringType&& mod_name, StringType&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)), m_lua(LuaMadeSimple::new_state()) { // Verify that there's a 'Scripts' directory // Give the full path to the 'Scripts' directory to the mod container - m_scripts_path = m_mod_path + L"\\scripts"; + m_scripts_path = m_mod_path / STR("scripts"); // If the 'Scripts' directory doesn't exist then mark the mod as non-installable and move on to the next mod if (!std::filesystem::exists(m_scripts_path)) @@ -859,7 +859,7 @@ No overload found for function 'StaticFindObject'. // Ignores any params after P1 if (lua.is_string()) { - Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_wstring(lua.get_string())); + Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, ensure_str(lua.get_string())); // Construct a Lua object of type 'UObject' // Auto constructing is nullptr safe @@ -883,7 +883,7 @@ No overload found for function 'StaticFindObject'. Unreal::UClass* param_class{}; Unreal::UObject* param_in_outer{}; - std::wstring param_name{}; + StringType param_name{}; bool param_exact_class{}; // P1 (Class), userdata @@ -919,7 +919,7 @@ No overload found for function 'StaticFindObject'. // P3 (Name), string if (lua.is_string()) { - param_name = to_wstring(lua.get_string()); + param_name = ensure_str(lua.get_string()); } else { @@ -961,7 +961,7 @@ No overload found for function 'FindFirstOf'. // Ignores any params after P1 if (lua.is_string()) { - Unreal::UObject* object = Unreal::UObjectGlobals::FindFirstOf(to_wstring(lua.get_string())); + Unreal::UObject* object = Unreal::UObjectGlobals::FindFirstOf(ensure_str(lua.get_string())); // Construct a Lua object of type 'UObject' // Auto constructing is nullptr safe @@ -1137,7 +1137,7 @@ No overload found for function 'RegisterKeyBindAsync'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(lua.handle_error(e.what()))); + Output::send(STR("{}\n"), ensure_str(lua.handle_error(e.what()))); } }; @@ -1256,7 +1256,7 @@ No overload found for function 'RegisterKeyBind'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(lua.handle_error(e.what()))); + Output::send(STR("{}\n"), ensure_str(lua.handle_error(e.what()))); } }; @@ -1355,8 +1355,8 @@ No overload found for function 'UnregisterHook'. lua.throw_error(error_overload_not_found); } - std::wstring function_name = to_wstring(lua.get_string()); - std::wstring function_name_no_prefix = function_name.substr(function_name.find_first_of(L" ") + 1, function_name.size()); + auto function_name = ensure_str(lua.get_string()); + auto function_name_no_prefix = function_name.substr(function_name.find_first_of(STR(" ")) + 1, function_name.size()); Unreal::UFunction* unreal_function = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, function_name_no_prefix); if (!unreal_function) @@ -1617,9 +1617,9 @@ No overload found for function 'RegisterCustomProperty'. struct PropertyInfo { - std::wstring name{}; + StringType name{}; PropertyTypeInfo type{}; // Figure out what to do here, it shouldn't be just a string - std::wstring belongs_to_class{}; + StringType belongs_to_class{}; int32_t offset_internal{-1}; int32_t element_size{-1}; // Is this required for trivial types like integers and floats ? @@ -1718,12 +1718,12 @@ No overload found for function 'RegisterCustomProperty'. }; // Always required, for all property types - property_info.name = to_wstring(lua_table.get_string_field("Name")); + property_info.name = ensure_str(lua_table.get_string_field("Name")); property_info.type.name = lua_table.get_table_field("Type").get_string_field("Name"); property_info.type.size = verify_and_convert_int64_to_int32("Type", "Size"); property_info.type.ffieldclass_pointer = reinterpret_cast(lua_table.get_table_field("Type").get_int_field("FFieldClassPointer")); property_info.type.static_pointer = reinterpret_cast(lua_table.get_table_field("Type").get_int_field("StaticPointer")); - property_info.belongs_to_class = to_wstring(lua_table.get_string_field("BelongsToClass")); + property_info.belongs_to_class = ensure_str(lua_table.get_string_field("BelongsToClass")); std::string oi_property_name; int32_t oi_relative_offset{}; @@ -1774,7 +1774,7 @@ No overload found for function 'RegisterCustomProperty'. if (property_info.offset_internal_is_table) { - auto name = Unreal::FName(to_wstring(oi_property_name)); + auto name = Unreal::FName(ensure_str(oi_property_name)); Unreal::FProperty* oi_property = belongs_to_class->FindProperty(name); if (!oi_property) { @@ -1811,14 +1811,14 @@ No overload found for function 'RegisterCustomProperty'. printf_s("Registered Custom Property\n"); printf_s("PropertyInfo {\n"); - printf_s("\tName: %S\n", property_info.name.c_str()); + printf_s("\tName: %S\n", FromCharTypePtr(property_info.name.c_str())); printf_s("\tType {\n"); printf_s("\t\tName: %s\n", property_info.type.name.data()); printf_s("\t\tSize: 0x%X\n", property_info.type.size); printf_s("\t\tFFieldClassPointer: 0x%p\n", property_info.type.ffieldclass_pointer); printf_s("\t\tStaticPointer: 0x%p\n", property_info.type.static_pointer); printf_s("\t}\n"); - printf_s("\tBelongsToClass: %S\n", property_info.belongs_to_class.c_str()); + printf_s("\tBelongsToClass: %S\n", FromCharTypePtr(property_info.belongs_to_class.c_str())); printf_s("\tOffsetInternal: 0x%X\n", property_info.offset_internal); if (property_info.is_array_property) @@ -1870,7 +1870,7 @@ No overload found for function 'NotifyOnNewObject'. lua.throw_error(error_overload_not_found); } - std::wstring class_name = to_wstring(lua.get_string()); + auto class_name = ensure_str(lua.get_string()); if (!lua.is_function()) { @@ -1906,7 +1906,7 @@ No overload found for function 'RegisterCustomEvent'. lua.throw_error(error_overload_not_found); } - std::wstring event_name = to_wstring(lua.get_string()); + auto event_name = ensure_str(lua.get_string()); if (!lua.is_function()) { @@ -1942,7 +1942,7 @@ No overload found for function 'UnregisterCustomEvent'. { lua.throw_error(error_overload_not_found); } - auto custom_event_name = to_wstring(lua.get_string()); + auto custom_event_name = ensure_str(lua.get_string()); LuaMod::m_custom_event_callbacks.erase(custom_event_name); @@ -2486,7 +2486,7 @@ No overload found for function 'RegisterConsoleCommandGlobalHandler'. { throw std::runtime_error{error_overload_not_found}; } - auto command_name = to_wstring(lua.get_string()); + auto command_name = ensure_str(lua.get_string()); if (!lua.is_function()) { @@ -2521,7 +2521,7 @@ No overload found for function 'RegisterConsoleCommandHandler'. { throw std::runtime_error{error_overload_not_found}; } - auto command_name = to_wstring(lua.get_string()); + auto command_name = ensure_str(lua.get_string()); if (!lua.is_function()) { @@ -2561,7 +2561,7 @@ No overload found for function 'LoadAsset'. { throw std::runtime_error{error_overload_not_found}; } - auto asset_path_and_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + auto asset_path_and_name = Unreal::FName(ensure_str(lua.get_string()), Unreal::FNAME_Add); auto* asset_registry = static_cast(Unreal::UAssetRegistryHelpers::GetAssetRegistry().ObjectPointer); if (!asset_registry) @@ -2612,7 +2612,7 @@ No overload found for function 'FindObject'. bool could_be_in_class{}; if (lua.is_string()) { - object_class_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_class_name = Unreal::FName(ensure_str(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2655,7 +2655,7 @@ No overload found for function 'FindObject'. bool could_be_object_short_name{}; if (lua.is_string()) { - object_short_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_short_name = Unreal::FName(ensure_str(lua.get_string()), Unreal::FNAME_Add); could_be_object_short_name = true; } else if (lua.is_userdata()) @@ -2739,7 +2739,7 @@ No overload found for function 'FindObject'. if (could_be_in_class && could_be_in_outer && could_be_in_name) { - LuaType::auto_construct_object(lua, Unreal::UObjectGlobals::FindObject(in_class, in_outer, to_wstring(in_name), exact_class)); + LuaType::auto_construct_object(lua, Unreal::UObjectGlobals::FindObject(in_class, in_outer, ensure_str(in_name), exact_class)); } else { @@ -2786,7 +2786,7 @@ No overload found for function 'FindObjects'. bool object_class_name_supplied{true}; if (lua.is_string()) { - object_class_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_class_name = Unreal::FName(ensure_str(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2824,7 +2824,7 @@ No overload found for function 'FindObjects'. Unreal::FName object_short_name{}; if (lua.is_string()) { - object_short_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_short_name = Unreal::FName(ensure_str(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2966,8 +2966,8 @@ No overload found for function 'RegisterHook'. lua.throw_error(error_overload_not_found); } - std::wstring function_name = to_wstring(lua.get_string()); - std::wstring function_name_no_prefix = function_name.substr(function_name.find_first_of(L"/"), function_name.size()); + auto function_name = ensure_str(lua.get_string()); + auto function_name_no_prefix = function_name.substr(function_name.find_first_of(STR("/")), function_name.size()); if (!lua.is_function()) { @@ -3250,7 +3250,7 @@ No overload found for function 'FPackageName:IsShortPackageName'. lua.throw_error(error_overload_not_found); } - File::StringType PossiblyLongName = to_wstring(lua.get_string()); + File::StringType PossiblyLongName = ensure_str(lua.get_string()); lua.set_bool(Unreal::FPackageName::IsShortPackageName(PossiblyLongName)); return 1; @@ -3267,7 +3267,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. lua.throw_error(error_overload_not_found); } - File::StringType InLongPackageName = to_wstring(lua.get_string()); + File::StringType InLongPackageName = ensure_str(lua.get_string()); lua.set_bool(Unreal::FPackageName::IsValidLongPackageName(InLongPackageName)); return 1; @@ -3364,11 +3364,11 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. // Don't crash on syntax errors. try { - main_lua()->execute_file(m_scripts_path + L"\\main.lua"); + main_lua()->execute_file((m_scripts_path / STR("main.lua")).string()); } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(e.what())); + Output::send(STR("{}\n"), ensure_str(e.what())); } } @@ -3564,8 +3564,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } else { - std::wstring return_property_type_name = return_property_type.ToString(); - std::wstring return_property_name = return_property->GetName(); + auto return_property_type_name = return_property_type.ToString(); + auto return_property_name = return_property->GetName(); Output::send(STR("Tried altering return value of a custom BP function without a registered handler for return type Return " "property '{}' of type '{}' not supported."), @@ -3779,7 +3779,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(e.what())); + Output::send(STR("{}\n"), ensure_str(e.what())); } if (cancel) @@ -4018,36 +4018,36 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. Unreal::Hook::RegisterProcessConsoleExecCallback([](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { auto logln = [&ar](const File::StringType& log_message) { Output::send(fmt::format(STR("{}\n"), log_message)); - ar.Log(log_message.c_str()); + ar.Log(FromCharTypePtr(log_message.c_str())); }; - if (!LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luastart"))) + if (!LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{ToCharTypePtr(cmd)}, File::StringViewType {STR("luastart")})) { start_console_lua_executor(); logln(STR("Console Lua executor started")); return true; } - else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luastop"))) + else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{ToCharTypePtr(cmd)}, File::StringViewType {STR("luastop")})) { stop_console_lua_executor(); logln(STR("Console Lua executor stopped")); return true; } - else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luarestart"))) + else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{ToCharTypePtr(cmd)}, File::StringViewType {STR("luarestart")})) { stop_console_lua_executor(); start_console_lua_executor(); logln(STR("Console Lua executor restarted")); return true; } - else if (String::iequal(File::StringViewType{cmd}, STR("clear"))) + else if (String::iequal(File::StringViewType{ToCharTypePtr(cmd)}, File::StringViewType{STR("clear")})) { // TODO: Replace with proper implementation when we have UGameViewportClient and UConsole. // This should be fairly cross-game & cross-engine-version compatible even without the proper implementation. // This is because I don't think they've changed the layout here and we have a reflected property right before the unreflected one that we're looking for. - Unreal::UObject** console = static_cast(context->GetValuePtrByPropertyName(STR("ViewportConsole"))); + Unreal::UObject** console = static_cast(context->GetValuePtrByPropertyName(FromCharTypePtr(STR("ViewportConsole")))); auto* default_texture_white = std::bit_cast*>( - static_cast((*console)->GetValuePtrByPropertyNameInChain(STR("DefaultTexture_White"))) + 0x8); + static_cast((*console)->GetValuePtrByPropertyNameInChain(FromCharTypePtr(STR("DefaultTexture_White")))) + 0x8); auto* scrollback = std::bit_cast(std::bit_cast(default_texture_white) + 0x10); default_texture_white->SetNum(0); default_texture_white->SetMax(0); @@ -4082,7 +4082,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } catch (std::runtime_error& e) { - logln(to_wstring(e.what())); + logln(ensure_str(e.what())); } // We always return true when the console Lua executor is enabled in order to suppress other handlers @@ -4098,8 +4098,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. Unreal::Hook::RegisterProcessConsoleExecGlobalPreCallback( [](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = File::StringType {ToCharTypePtr(cmd)}; + auto command_parts = explode_by_occurrence(command, STR(' ')); for (const auto& callback_data : m_process_console_exec_pre_callbacks) { @@ -4154,8 +4154,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. Unreal::Hook::RegisterProcessConsoleExecGlobalPostCallback( [](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = File::StringType {ToCharTypePtr(cmd)}; + auto command_parts = explode_by_occurrence(command, STR(' ')); for (const auto& callback_data : m_process_console_exec_post_callbacks) { @@ -4216,8 +4216,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = File::StringType {ToCharTypePtr(cmd)}; + auto command_parts = explode_by_occurrence(command, STR(' ')); File::StringType command_name; if (command_parts.size() > 1) { @@ -4276,8 +4276,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. (void)executor; return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = File::StringType{ToCharTypePtr(cmd)}; + auto command_parts = explode_by_occurrence(command, STR(' ')); File::StringType command_name; if (command_parts.size() > 1) { @@ -4396,8 +4396,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. catch (std::runtime_error& e) { Output::send(STR("[{}] {}\n"), - to_wstring(action.type == LuaMod::ActionType::Loop ? "LoopAsync" : "DelayedAction"), - to_wstring(e.what())); + ensure_str(action.type == LuaMod::ActionType::Loop ? "LoopAsync" : "DelayedAction"), + ensure_str(e.what())); } return result; diff --git a/UE4SS/src/Mod/Mod.cpp b/UE4SS/src/Mod/Mod.cpp index 65550fa71..40f6dda0f 100644 --- a/UE4SS/src/Mod/Mod.cpp +++ b/UE4SS/src/Mod/Mod.cpp @@ -52,11 +52,11 @@ namespace RC { - Mod::Mod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) : m_program(program), m_mod_name(mod_name), m_mod_path(mod_path) + Mod::Mod(UE4SSProgram& program, StringType&& mod_name, std::filesystem::path&& mod_path) : m_program(program), m_mod_name(mod_name), m_mod_path(mod_path) { } - auto Mod::get_name() const -> std::wstring_view + auto Mod::get_name() const -> StringViewType { return m_mod_name; } diff --git a/UE4SS/src/ObjectDumper/ObjectToString.cpp b/UE4SS/src/ObjectDumper/ObjectToString.cpp index 86f838fa1..017d98ff0 100644 --- a/UE4SS/src/ObjectDumper/ObjectToString.cpp +++ b/UE4SS/src/ObjectDumper/ObjectToString.cpp @@ -56,54 +56,54 @@ namespace RC::ObjectDumper return object_to_string_complex_functions.contains(hash); } - auto object_trivial_dump_to_string(void* p_this, std::wstring& out_line, const wchar_t* post_delimiter) -> void + auto object_trivial_dump_to_string(void* p_this, StringType& out_line, const CharType* post_delimiter) -> void { UObject* p_typed_this = static_cast(p_this); - out_line.append(fmt::format(L"[{:016X}] ", reinterpret_cast(p_this))); + out_line.append(fmt::format(STR("[{:016X}] "), reinterpret_cast(p_this))); out_line.append(p_typed_this->GetFullName()); - out_line.append(fmt::format(L" [n: {:X}] [c: {:016X}] [or: {:016X}]", + out_line.append(fmt::format(STR(" [n: {:X}] [c: {:016X}] [or: {:016X}]"), p_typed_this->GetNamePrivate().GetComparisonIndex(), reinterpret_cast(p_typed_this->GetClassPrivate()), reinterpret_cast(p_typed_this->GetOuterPrivate()))); } - auto object_to_string(void* p_this, std::wstring& out_line) -> void + auto object_to_string(void* p_this, StringType& out_line) -> void { object_trivial_dump_to_string(p_this, out_line); } - auto property_trivial_dump_to_string(void* p_this, std::wstring& out_line) -> void + auto property_trivial_dump_to_string(void* p_this, StringType& out_line) -> void { FProperty* p_typed_this = static_cast(p_this); - out_line.append(fmt::format(L"[{:016X}] ", reinterpret_cast(p_this))); + out_line.append(fmt::format(STR("[{:016X}] "), reinterpret_cast(p_this))); out_line.append(p_typed_this->GetFullName()); - out_line.append(fmt::format(L" [o: {:X}] ", p_typed_this->GetOffset_Internal())); + out_line.append(fmt::format(STR(" [o: {:X}] "), p_typed_this->GetOffset_Internal())); auto property_class = p_typed_this->GetClass(); - out_line.append(fmt::format(L"[n: {:X}] [c: {:016X}]", p_typed_this->GetFName().GetComparisonIndex(), property_class.HashObject())); + out_line.append(fmt::format(STR("[n: {:X}] [c: {:016X}]"), p_typed_this->GetFName().GetComparisonIndex(), property_class.HashObject())); if (Version::IsAtLeast(4, 25)) { - out_line.append(fmt::format(L" [owr: {:016X}]", p_typed_this->GetOwnerVariant().HashObject())); + out_line.append(fmt::format(STR(" [owr: {:016X}]"), p_typed_this->GetOwnerVariant().HashObject())); } } - auto property_to_string(void* p_this, std::wstring& out_line) -> void + auto property_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); } - auto arrayproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto arrayproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FArrayProperty* p_typed_this = static_cast(p_this); - out_line.append(fmt::format(L" [ai: {:016X}]", reinterpret_cast(p_typed_this->GetInner()))); + out_line.append(fmt::format(STR(" [ai: {:016X}]"), reinterpret_cast(p_typed_this->GetInner()))); } - auto arrayproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto arrayproperty_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { FProperty* array_inner = static_cast(p_this)->GetInner(); auto array_inner_class = array_inner->GetClass().HashObject(); @@ -116,7 +116,7 @@ namespace RC::ObjectDumper { // If this code is executed then we'll be having another line before we return to the dumper, so we need to explicitly add a new line // If this code is not executed then we'll not be having another line and the dumper will add the new line - out_line.append(L"\n"); + out_line.append(STR("\n")); get_to_string_complex(array_inner_class)(array_inner, out_line, [&]([[maybe_unused]] void* prop) { // It's possible that a new line is supposed to be appended here @@ -132,17 +132,17 @@ namespace RC::ObjectDumper } } - auto mapproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto mapproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FMapProperty* typed_this = static_cast(p_this); FProperty* key_property = typed_this->GetKeyProp(); FProperty* value_property = typed_this->GetValueProp(); - out_line.append(fmt::format(L" [kp: {:016X}] [vp: {:016X}]", reinterpret_cast(key_property), reinterpret_cast(value_property))); + out_line.append(fmt::format(STR(" [kp: {:016X}] [vp: {:016X}]"), reinterpret_cast(key_property), reinterpret_cast(value_property))); } - auto mapproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto mapproperty_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { FMapProperty* typed_this = static_cast(p_this); FProperty* key_property = typed_this->GetKeyProp(); @@ -159,7 +159,7 @@ namespace RC::ObjectDumper { // If this code is executed then we'll be having another line before we return to the dumper, so we need to explicitly add a new line // If this code is not executed then we'll not be having another line and the dumper will add the new line - out_line.append(L"\n"); + out_line.append(STR("\n")); get_to_string_complex(property_class)(property, out_line, [&]([[maybe_unused]] void* prop) {}); } @@ -177,83 +177,83 @@ namespace RC::ObjectDumper dump_property(value_property, value_property_class); } - auto classproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto classproperty_to_string(void* p_this, StringType& out_line) -> void { FClassProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); // mc = MetaClass - out_line.append(fmt::format(L" [mc: {:016X}]", reinterpret_cast(typed_this->GetMetaClass()))); + out_line.append(fmt::format(STR(" [mc: {:016X}]"), reinterpret_cast(typed_this->GetMetaClass()))); } - auto delegateproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto delegateproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FDelegateProperty* p_typed_this = static_cast(p_this); - out_line.append(fmt::format(L" [df: {:016X}]", reinterpret_cast(p_typed_this->GetSignatureFunction()))); + out_line.append(fmt::format(STR(" [df: {:016X}]"), reinterpret_cast(p_typed_this->GetSignatureFunction()))); } - auto fieldpathproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto fieldpathproperty_to_string(void* p_this, StringType& out_line) -> void { FFieldPathProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(fmt::format(L" [pc: {:016X}]", reinterpret_cast(typed_this->GetPropertyClass()))); + out_line.append(fmt::format(STR(" [pc: {:016X}]"), reinterpret_cast(typed_this->GetPropertyClass()))); } - auto interfaceproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto interfaceproperty_to_string(void* p_this, StringType& out_line) -> void { FInterfaceProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(fmt::format(L" [ic: {:016X}]", reinterpret_cast(typed_this->GetInterfaceClass()))); + out_line.append(fmt::format(STR(" [ic: {:016X}]"), reinterpret_cast(typed_this->GetInterfaceClass()))); } - auto multicastdelegateproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto multicastdelegateproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FMulticastDelegateProperty* p_typed_this = static_cast(p_this); - out_line.append(fmt::format(L" [df: {:016X}]", reinterpret_cast(p_typed_this->GetSignatureFunction()))); + out_line.append(fmt::format(STR(" [df: {:016X}]"), reinterpret_cast(p_typed_this->GetSignatureFunction()))); } - auto objectproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto objectproperty_to_string(void* p_this, StringType& out_line) -> void { FObjectProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(fmt::format(L" [pc: {:016X}]", reinterpret_cast(typed_this->GetPropertyClass()))); + out_line.append(fmt::format(STR(" [pc: {:016X}]"), reinterpret_cast(typed_this->GetPropertyClass()))); } - auto structproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto structproperty_to_string(void* p_this, StringType& out_line) -> void { FStructProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(fmt::format(L" [ss: {:016X}]", reinterpret_cast(typed_this->GetStruct()))); + out_line.append(fmt::format(STR(" [ss: {:016X}]"), reinterpret_cast(typed_this->GetStruct()))); } - auto enumproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto enumproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); auto* typed_this = static_cast(p_this); - out_line.append(fmt::format(L" [em: {:016X}]", reinterpret_cast(typed_this->GetEnum()))); + out_line.append(fmt::format(STR(" [em: {:016X}]"), reinterpret_cast(typed_this->GetEnum()))); } - auto boolproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto boolproperty_to_string(void* p_this, StringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); auto* typed_this = static_cast(p_this); if (typed_this->GetFieldMask() != 255) { - out_line.append(fmt::format(L" [fm: {:X}] [bm: {:X}]", typed_this->GetFieldMask(), typed_this->GetByteMask())); + out_line.append(fmt::format(STR(" [fm: {:X}] [bm: {:X}]"), typed_this->GetFieldMask(), typed_this->GetByteMask())); } } - auto enum_to_string(void* p_this, std::wstring& out_line) -> void + auto enum_to_string(void* p_this, StringType& out_line) -> void { object_trivial_dump_to_string(p_this, out_line); @@ -261,24 +261,24 @@ namespace RC::ObjectDumper for (auto& Elem : typed_this->ForEachName()) { - out_line.append(fmt::format(L"\n[{:016X}] {} [n: {:X}] [v: {}]", 0, Elem.Key.ToString(), Elem.Key.GetComparisonIndex(), Elem.Value)); + out_line.append(fmt::format(STR("\n[{:016X}] {} [n: {:X}] [v: {}]"), 0, Elem.Key.ToString(), Elem.Key.GetComparisonIndex(), Elem.Value)); } } - auto struct_to_string(void* p_this, std::wstring& out_line) -> void + auto struct_to_string(void* p_this, StringType& out_line) -> void { UStruct* typed_this = static_cast(p_this); object_trivial_dump_to_string(p_this, out_line); - out_line.append(fmt::format(L" [sps: {:016X}]", reinterpret_cast(typed_this->GetSuperStruct()))); + out_line.append(fmt::format(STR(" [sps: {:016X}]"), reinterpret_cast(typed_this->GetSuperStruct()))); } - auto function_to_string(void* p_this, std::wstring& out_line) -> void + auto function_to_string(void* p_this, StringType& out_line) -> void { - object_trivial_dump_to_string(p_this, out_line, L":"); + object_trivial_dump_to_string(p_this, out_line, STR(":")); } - auto scriptstruct_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto scriptstruct_to_string_complex(void* p_this, StringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { UScriptStruct* script_struct = static_cast(p_this); diff --git a/UE4SS/src/SDKGenerator/Common.cpp b/UE4SS/src/SDKGenerator/Common.cpp index 77439bb4e..d3077224a 100644 --- a/UE4SS/src/SDKGenerator/Common.cpp +++ b/UE4SS/src/SDKGenerator/Common.cpp @@ -74,7 +74,7 @@ namespace RC::UEGenerator auto get_native_enum_name(UEnum* uenum, bool include_type) -> File::StringType { - std::wstring result_string; + StringType result_string; // Seems to be not needed, because enum objects, unlike classes or structs, retain their normal E prefix // ResultString.append(STR("E")); @@ -90,7 +90,7 @@ namespace RC::UEGenerator auto get_native_struct_name(UScriptStruct* script_struct) -> File::StringType { - std::wstring result_string; + StringType result_string; result_string.append(STR("F")); result_string.append(script_struct->GetName()); @@ -100,7 +100,7 @@ namespace RC::UEGenerator auto sanitize_property_name(const File::StringType& property_name) -> File::StringType { - std::wstring resulting_name = property_name; + StringType resulting_name = property_name; // Remove heading underscore, used by private variables in some games if (resulting_name.length() >= 2 && resulting_name[0] == '_') @@ -123,14 +123,14 @@ namespace RC::UEGenerator auto generate_delegate_name(FProperty* property, const File::StringType& context_name) -> File::StringType { - const std::wstring property_name = sanitize_property_name(property->GetName()); + const StringType property_name = sanitize_property_name(property->GetName()); return fmt::format(STR("F{}{}"), context_name, property_name); } auto generate_property_cxx_name(FProperty* property, bool is_top_level_declaration, UObject* class_context, EnableForwardDeclarations enable_forward_declarations) -> File::StringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const StringType field_class_name = property->GetClass().GetName(); // Byte Property if (property->IsA()) @@ -141,7 +141,7 @@ namespace RC::UEGenerator if (enum_value != NULL) { // Non-EnumClass enumerations should be wrapped into TEnumAsByte according to UHT - const std::wstring enum_type_name = get_native_enum_name(enum_value); + const StringType enum_type_name = get_native_enum_name(enum_value); return fmt::format(STR("TEnumAsByte<{}>"), enum_type_name); } return STR("uint8"); @@ -158,7 +158,7 @@ namespace RC::UEGenerator throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const StringType enum_type_name = get_native_enum_name(uenum); return enum_type_name; } @@ -251,7 +251,7 @@ namespace RC::UEGenerator return STR("TSoftClassPtr"); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const StringType meta_class_name = get_native_class_name(meta_class, false); return fmt::format(STR("TSoftClassPtr<{}>"), meta_class_name); } @@ -268,7 +268,7 @@ namespace RC::UEGenerator return STR("UObject*"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("{}*"), property_class_name); } @@ -282,7 +282,7 @@ namespace RC::UEGenerator } else { - const auto property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TObjectPtr<{}>"), property_class_name); } } @@ -335,7 +335,7 @@ namespace RC::UEGenerator return STR("TSoftObjectPtr"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TSoftObjectPtr<{}>"), property_class_name); } @@ -370,7 +370,7 @@ namespace RC::UEGenerator throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const StringType native_struct_name = get_native_struct_name(script_struct); return native_struct_name; } @@ -379,7 +379,7 @@ namespace RC::UEGenerator { FDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -389,7 +389,7 @@ namespace RC::UEGenerator { FMulticastInlineDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -397,7 +397,7 @@ namespace RC::UEGenerator { FMulticastSparseDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -405,7 +405,7 @@ namespace RC::UEGenerator if (property->IsA()) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); + const StringType property_class_name = field_path_property->GetPropertyClass()->GetName(); return fmt::format(STR("TFieldPath"), property_class_name); } @@ -433,7 +433,7 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_cxx_name(element_prop, is_top_level_declaration, class_context); + const StringType element_property_type = generate_property_cxx_name(element_prop, is_top_level_declaration, class_context); return fmt::format(STR("TSet<{}>"), element_property_type); } @@ -482,7 +482,7 @@ namespace RC::UEGenerator auto generate_property_lua_name(FProperty* property, bool is_top_level_declaration, UObject* class_context) -> File::StringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const StringType field_class_name = property->GetClass().GetName(); // Byte Property if (field_class_name == STR("ByteProperty")) @@ -493,7 +493,7 @@ namespace RC::UEGenerator if (enum_value != NULL) { // Non-EnumClass enumerations should be wrapped into TEnumAsByte according to UHT - const std::wstring enum_type_name = get_native_enum_name(enum_value); + const StringType enum_type_name = get_native_enum_name(enum_value); return fmt::format(STR("{}"), enum_type_name); } return STR("uint8"); @@ -510,7 +510,7 @@ namespace RC::UEGenerator throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const StringType enum_type_name = get_native_enum_name(uenum); return enum_type_name; } @@ -571,7 +571,7 @@ namespace RC::UEGenerator return STR("UObject"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("{}"), property_class_name); } @@ -585,7 +585,7 @@ namespace RC::UEGenerator } else { - const auto property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TObjectPtr<{}>"), property_class_name); } } @@ -630,7 +630,7 @@ namespace RC::UEGenerator return STR("TSoftObjectPtr"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TSoftObjectPtr<{}>"), property_class_name); } @@ -666,7 +666,7 @@ namespace RC::UEGenerator return STR("TSoftClassPtr"); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const StringType meta_class_name = get_native_class_name(meta_class, false); return fmt::format(STR("TSoftClassPtr<{}>"), meta_class_name); } @@ -697,7 +697,7 @@ namespace RC::UEGenerator throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const StringType native_struct_name = get_native_struct_name(script_struct); return native_struct_name; } @@ -706,7 +706,7 @@ namespace RC::UEGenerator { FDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -716,7 +716,7 @@ namespace RC::UEGenerator { FMulticastInlineDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -724,7 +724,7 @@ namespace RC::UEGenerator { FMulticastSparseDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const StringType delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); return delegate_type_name; } @@ -732,7 +732,7 @@ namespace RC::UEGenerator if (field_class_name == STR("FieldPathProperty")) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); + const StringType property_class_name = field_path_property->GetPropertyClass()->GetName(); return fmt::format(STR("TFieldPath"), property_class_name); } @@ -753,7 +753,7 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_lua_name(element_prop, is_top_level_declaration, class_context); + const StringType element_property_type = generate_property_lua_name(element_prop, is_top_level_declaration, class_context); return fmt::format(STR("TSet<{}>"), element_property_type); } diff --git a/UE4SS/src/SDKGenerator/Generator.cpp b/UE4SS/src/SDKGenerator/Generator.cpp index cb3b5d113..24906ba69 100644 --- a/UE4SS/src/SDKGenerator/Generator.cpp +++ b/UE4SS/src/SDKGenerator/Generator.cpp @@ -246,7 +246,7 @@ namespace RC::UEGenerator }); } - auto get_class_name(const auto& x) -> std::wstring + auto get_class_name(const auto& x) -> StringType { // Using this method instead of regex because it is extremely slow auto class_name = x.substr(x.find(STR(' ')) + 1); @@ -678,7 +678,7 @@ namespace RC::UEGenerator if (!generated_file.secondary_file_has_no_contents) { - generated_file.primary_file.write_string_to_file(fmt::format(STR("#include \"{}\"\n\n"), generated_file.secondary_file_name.filename().c_str())); + generated_file.primary_file.write_string_to_file(fmt::format(STR("#include \"{}\"\n\n"), ensure_str(generated_file.secondary_file_name.filename()))); } } auto generate_file_footer(GeneratedFile& generated_file) -> void @@ -783,7 +783,7 @@ namespace RC::UEGenerator } catch (std::exception& e) { - Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), to_wstring(e.what())); + Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), ensure_str(e.what())); continue; } @@ -959,7 +959,7 @@ namespace RC::UEGenerator { Output::send(STR("Could not generate function '{}' because: {}\n"), function_info.function->GetFullName(), - to_wstring(e.what())); + ensure_str(e.what())); return; } @@ -994,7 +994,7 @@ namespace RC::UEGenerator { Output::send(STR("Could not generate function '{}' because: {}\n"), function_info.function->GetFullName(), - to_wstring(e.what())); + ensure_str(e.what())); return; } @@ -1171,7 +1171,7 @@ namespace RC::UEGenerator } catch (std::exception& e) { - Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), to_wstring(e.what())); + Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), ensure_str(e.what())); continue; } @@ -1248,7 +1248,7 @@ namespace RC::UEGenerator { Output::send(STR("Could not generate function '{}' because: {}\n"), function_info.function->GetFullName(), - to_wstring(e.what())); + ensure_str(e.what())); return; } } @@ -1264,7 +1264,7 @@ namespace RC::UEGenerator { Output::send(STR("Could not generate function '{}' because: {}\n"), function_info.function->GetFullName(), - to_wstring(e.what())); + ensure_str(e.what())); return; } } diff --git a/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp b/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp index f724a7dd0..740127671 100644 --- a/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp +++ b/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp @@ -50,6 +50,9 @@ #include #pragma warning(default : 4005) +#include +#include + namespace RC::UEGenerator { using namespace RC::Unreal; @@ -57,6 +60,8 @@ namespace RC::UEGenerator std::map UEHeaderGenerator::m_used_file_names{}; std::map UEHeaderGenerator::m_dependency_object_to_unique_id{}; + #define ToStringFmt(numeric_value) fmt::format(STR("{}"), numeric_value) + auto static is_subtype_struct_valid(UScriptStruct* subtype) -> bool { @@ -132,7 +137,7 @@ namespace RC::UEGenerator } } - auto string_to_uppercase(std::wstring s) -> std::wstring + auto string_to_uppercase(StringType s) -> StringType { std::transform(s.begin(), s.end(), s.begin(), [](wchar_t c) { return towupper(c); @@ -142,8 +147,8 @@ namespace RC::UEGenerator class FlagFormatHelper { - std::set m_switches; - std::map> m_parameters; + std::set m_switches; + std::map> m_parameters; std::shared_ptr m_meta_helper; FlagFormatHelper(bool is_root_helper) @@ -159,12 +164,12 @@ namespace RC::UEGenerator { } - auto add_switch(const std::wstring& switch_name) -> void + auto add_switch(const StringType& switch_name) -> void { m_switches.insert(switch_name); } - auto add_parameter(const std::wstring& parameter_name, const std::wstring& parameter_value) -> void + auto add_parameter(const StringType& parameter_name, const StringType& parameter_value) -> void { if (parameter_name == STR("meta")) { @@ -187,11 +192,11 @@ namespace RC::UEGenerator return m_meta_helper.get(); } - auto build_flag_string() const -> std::wstring + auto build_flag_string() const -> StringType { - std::wstring resulting_string; + StringType resulting_string; - for (const std::wstring& switch_name : m_switches) + for (const StringType& switch_name : m_switches) { resulting_string.append(switch_name); resulting_string.append(STR(", ")); @@ -201,13 +206,13 @@ namespace RC::UEGenerator { resulting_string.append(parameter_pair.first); resulting_string.append(STR("=")); - const std::set& parameter_values = parameter_pair.second; + const std::set& parameter_values = parameter_pair.second; if (parameter_values.size() != 1) { resulting_string.append(STR("(")); - for (const std::wstring& parameter_value : parameter_values) + for (const StringType& parameter_value : parameter_values) { resulting_string.append(parameter_value); resulting_string.append(STR(", ")); @@ -228,7 +233,7 @@ namespace RC::UEGenerator if (m_meta_helper) { - const std::wstring meta_flag_string = m_meta_helper->build_flag_string(); + const StringType meta_flag_string = m_meta_helper->build_flag_string(); if (!meta_flag_string.empty()) { resulting_string.append(STR("meta=(")); @@ -246,7 +251,7 @@ namespace RC::UEGenerator } }; - auto UEHeaderGenerator::generate_module_build_file(const std::wstring& module_name) -> void + auto UEHeaderGenerator::generate_module_build_file(const StringType& module_name) -> void { const FFilePath module_file_path = m_root_directory / module_name / fmt::format(STR("{}.Build.cs"), module_name); GeneratedFile module_build_file = GeneratedFile(module_file_path); @@ -272,13 +277,13 @@ namespace RC::UEGenerator module_build_file.append_line(STR("PublicDependencyModuleNames.AddRange(new string[] {")); module_build_file.begin_indent_level(); - std::set all_module_dependencies = this->m_forced_module_dependencies; - std::set clean_module_dependencies{}; + std::set all_module_dependencies = this->m_forced_module_dependencies; + std::set clean_module_dependencies{}; add_module_and_sub_module_dependencies(clean_module_dependencies, module_name, false); all_module_dependencies.insert(clean_module_dependencies.begin(), clean_module_dependencies.end()); - for (const std::wstring& other_module_name : all_module_dependencies) + for (const StringType& other_module_name : all_module_dependencies) { module_build_file.append_line(fmt::format(STR("\"{}\","), other_module_name)); } @@ -295,7 +300,7 @@ namespace RC::UEGenerator module_build_file.serialize_file_content_to_disk(); } - auto UEHeaderGenerator::generate_module_implementation_file(const std::wstring& module_name) -> void + auto UEHeaderGenerator::generate_module_implementation_file(const StringType& module_name) -> void { const FFilePath module_file_path = m_root_directory / module_name / STR("Private") / fmt::format(STR("{}Module.cpp"), module_name); GeneratedFile module_impl_file = GeneratedFile(module_file_path); @@ -316,10 +321,10 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_interface_definition(UClass* uclass, GeneratedSourceFile& header_data) -> void { - const std::wstring interface_class_native_name = get_native_class_name(uclass); - const std::wstring interface_flags_string = generate_interface_flags(uclass); + const StringType interface_class_native_name = get_native_class_name(uclass); + const StringType interface_flags_string = generate_interface_flags(uclass); - std::wstring maybe_api_name; + StringType maybe_api_name; if ((uclass->GetClassFlags() & CLASS_RequiredAPI) != 0) { maybe_api_name.append(convert_module_name_to_api_name(header_data.get_header_module_name())); @@ -329,7 +334,7 @@ namespace RC::UEGenerator UClass* super_class = uclass->GetSuperClass(); header_data.add_dependency_object(super_class, DependencyLevel::Include); - std::wstring parent_interface_class_name = get_native_class_name(super_class); + StringType parent_interface_class_name = get_native_class_name(super_class); // Generate interface UCLASS declaration header_data.append_line(fmt::format(STR("UINTERFACE({})"), interface_flags_string)); @@ -343,8 +348,8 @@ namespace RC::UEGenerator header_data.append_line(STR("")); // Generate interface real class declaration - const std::wstring interface_native_name = get_native_class_name(uclass, true); - const std::wstring parent_interface_name = get_native_class_name(super_class, true); + const StringType interface_native_name = get_native_class_name(uclass, true); + const StringType parent_interface_name = get_native_class_name(super_class, true); header_data.append_line(fmt::format(STR("class {}{} : public {} {{"), maybe_api_name, interface_native_name, parent_interface_name)); header_data.begin_indent_level(); @@ -385,10 +390,10 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_object_definition(UClass* uclass, GeneratedSourceFile& header_data) -> void { - const std::wstring class_native_name = get_native_class_name(uclass); - const std::wstring class_flags_string = generate_class_flags(uclass); + const StringType class_native_name = get_native_class_name(uclass); + const StringType class_flags_string = generate_class_flags(uclass); - std::wstring maybe_api_name; + StringType maybe_api_name; if ((uclass->GetClassFlags() & CLASS_RequiredAPI) != 0) { maybe_api_name.append(convert_module_name_to_api_name(header_data.get_header_module_name())); @@ -396,7 +401,7 @@ namespace RC::UEGenerator } UClass* super_class = uclass->GetSuperClass(); - std::wstring parent_class_name; + StringType parent_class_name; if (super_class) { parent_class_name = get_native_class_name(super_class); @@ -411,13 +416,13 @@ namespace RC::UEGenerator header_data.add_dependency_object(super_class, DependencyLevel::Include); } - std::wstring interface_list_string; + StringType interface_list_string; auto implemented_interfaces = uclass->GetInterfaces(); for (const RC::Unreal::FImplementedInterface& uinterface : implemented_interfaces) { header_data.add_dependency_object(uinterface.Class, DependencyLevel::Include); - const std::wstring interface_name = get_native_class_name(uinterface.Class, true); + const StringType interface_name = get_native_class_name(uinterface.Class, true); interface_list_string.append(STR(", public ")); interface_list_string.append(interface_name); @@ -471,7 +476,7 @@ namespace RC::UEGenerator append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); // Generate constructor - std::wstring constructor_string; + StringType constructor_string; if (uclass->IsChildOf() || uclass->IsChildOf()) { constructor_string.append(STR("const FObjectInitializer& ObjectInitializer")); @@ -524,20 +529,20 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_struct_definition(UScriptStruct* script_struct, GeneratedSourceFile& header_data) -> void { - const std::wstring struct_native_name = get_native_struct_name(script_struct); - const std::wstring struct_flags_string = generate_struct_flags(script_struct); + const StringType struct_native_name = get_native_struct_name(script_struct); + const StringType struct_flags_string = generate_struct_flags(script_struct); - std::wstring api_macro_name = convert_module_name_to_api_name(header_data.get_header_module_name()); + StringType api_macro_name = convert_module_name_to_api_name(header_data.get_header_module_name()); api_macro_name.append(STR(" ")); bool is_struct_exported = (script_struct->GetStructFlags() & STRUCT_RequiredAPI) != 0; UScriptStruct* super_struct = script_struct->GetSuperScriptStruct(); - std::wstring parent_struct_declaration; + StringType parent_struct_declaration; if (super_struct) { header_data.add_dependency_object(super_struct, DependencyLevel::Include); - const std::wstring super_struct_native_name = get_native_struct_name(super_struct); + const StringType super_struct_native_name = get_native_struct_name(super_struct); parent_struct_declaration.append(fmt::format(STR(" : public {}"), super_struct_native_name)); } @@ -614,7 +619,7 @@ namespace RC::UEGenerator } else { - std::wstring underlying_type_string = underlying_type->second; + StringType underlying_type_string = underlying_type->second; header_data.append_line(fmt::format(STR("enum class {} : {} {{"), native_enum_name, underlying_type_string)); } @@ -694,7 +699,7 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_delegate_type_declaration(UFunction* signature_function, UClass* delegate_class, GeneratedSourceFile& header_data) -> void { - std::wstring owning_class; + StringType owning_class; if (delegate_class == nullptr) { owning_class = STR("UObject*"); @@ -716,10 +721,10 @@ namespace RC::UEGenerator const bool is_multicast = (function_flags & Unreal::FUNC_MulticastDelegate) != 0; const bool declared_const = (function_flags & FUNC_Const) != 0; - const std::wstring delegate_type_name = get_native_delegate_type_name(signature_function, nullptr, true); + const StringType delegate_type_name = get_native_delegate_type_name(signature_function, nullptr, true); FProperty* return_value_property = signature_function->GetReturnProperty(); - std::wstring delegate_macro_string; + StringType delegate_macro_string; // Delegate macro declaration is only allowed on the top level delegates, class-based types are limited to being implicit if (signature_function->GetOuterPrivate()->IsA()) @@ -732,7 +737,7 @@ namespace RC::UEGenerator PropertyTypeDeclarationContext context(delegate_type_name, &header_data); int32_t num_delegate_parameters = 0; - std::wstring delegate_parameter_list = + StringType delegate_parameter_list = generate_function_parameter_list(nullptr, signature_function, header_data, true, context.context_name, {}, &num_delegate_parameters); if (num_delegate_parameters > 0) { @@ -744,14 +749,14 @@ namespace RC::UEGenerator Output::send(STR("Invalid delegate parameter count in Delegate: {}. Using _TooMany\n"), delegate_type_name); } - std::wstring return_value_declaration; + StringType return_value_declaration; if (return_value_property != NULL) { return_value_declaration = generate_property_type_declaration(return_value_property, context); return_value_declaration.append(STR(", ")); } - std::wstring delegate_declaration_string = fmt::format(STR("{}DECLARE_DYNAMIC{}{}_DELEGATE{}{}{}({}{}{}{});"), + StringType delegate_declaration_string = fmt::format(STR("{}DECLARE_DYNAMIC{}{}_DELEGATE{}{}{}({}{}{}{});"), delegate_macro_string, is_multicast ? STR("_MULTICAST") : STR(""), is_sparse ? STR("_SPARSE") : STR(""), @@ -769,18 +774,18 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_object_implementation(UClass* uclass, GeneratedSourceFile& implementation_file) -> void { - const std::wstring class_native_name = get_native_class_name(uclass); + const StringType class_native_name = get_native_class_name(uclass); - std::wstring constructor_content_string; - std::wstring constructor_postfix_string; + StringType constructor_content_string; + StringType constructor_postfix_string; UClass* super_class = uclass->GetSuperClass(); - const std::wstring native_parent_class_name = super_class ? get_native_class_name(super_class) : STR("UObjectUtility"); + const StringType native_parent_class_name = super_class ? get_native_class_name(super_class) : STR("UObjectUtility"); // Generate constructor implementation except for overrides. // If class is a child of AActor we add the UObjectInitializer constructor. // This may not be required in all cases, but is necessary to override subcomponents and does not hurt anything. - std::wstring object_initializer_overrides; + StringType object_initializer_overrides; if (uclass->IsChildOf() || uclass->IsChildOf()) { constructor_content_string.append(STR("const FObjectInitializer& ObjectInitializer")); @@ -887,7 +892,7 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_struct_implementation(UScriptStruct* script_struct, GeneratedSourceFile& implementation_file) -> void { - const std::wstring struct_native_name = get_native_struct_name(script_struct); + const StringType struct_native_name = get_native_struct_name(script_struct); // Generate constructor implementation and initialize properties inside implementation_file.m_implementation_constructor.append(fmt::format(STR("{}::{}() {{"), struct_native_name, struct_native_name)); @@ -913,14 +918,14 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_property(UObject* uclass, FProperty* property, GeneratedSourceFile& header_data) -> void { - const std::wstring property_flags_string = generate_property_flags(property); + const StringType property_flags_string = generate_property_flags(property); bool is_bitmask_bool = false; PropertyTypeDeclarationContext Context(uclass->GetName(), &header_data, true, &is_bitmask_bool); - std::wstring property_type_string{}; + StringType property_type_string{}; bool type_is_valid = true; - std::wstring error_string{}; + StringType error_string{}; try { property_type_string = generate_property_type_declaration(property, Context); @@ -928,7 +933,7 @@ namespace RC::UEGenerator catch (std::exception& e) { type_is_valid = false; - error_string = to_wstring(e.what()); + error_string = ensure_str(e.what()); } if (!type_is_valid) @@ -941,11 +946,11 @@ namespace RC::UEGenerator return; } - std::wstring property_extra_declaration; + StringType property_extra_declaration; if (property->GetArrayDim() != 1) { property_extra_declaration.append(STR("[")); - property_extra_declaration.append(std::to_wstring(property->GetArrayDim())); + property_extra_declaration.append(ToStringFmt(property->GetArrayDim())); property_extra_declaration.append(STR("]")); } else if (is_bitmask_bool) @@ -967,10 +972,10 @@ namespace RC::UEGenerator bool generate_as_override) -> void { auto function_flags = function->GetFunctionFlags(); - const std::wstring context_name = uclass->GetName(); + const StringType context_name = uclass->GetName(); bool is_function_pure_virtual = generate_as_override; - std::wstring function_modifier_string; + StringType function_modifier_string; if ((function_flags & FUNC_Static) != 0) { function_modifier_string.append(STR("static ")); @@ -985,7 +990,7 @@ namespace RC::UEGenerator } FProperty* return_property = function->GetReturnProperty(); - std::wstring return_property_string; + StringType return_property_string; if (return_property != NULL) { PropertyTypeDeclarationContext context(uclass->GetName(), &header_data); @@ -996,17 +1001,17 @@ namespace RC::UEGenerator return_property_string = STR("void"); } - std::wstring function_extra_postfix_string; + StringType function_extra_postfix_string; if ((function_flags & FUNC_Const) != 0) { function_extra_postfix_string.append(STR(" const")); } if (is_function_pure_virtual) { - std::wstring return_statement_string; + StringType return_statement_string; if (return_property != NULL) { - const std::wstring default_property_value = generate_default_property_value(return_property, header_data, context_name); + const StringType default_property_value = generate_default_property_value(return_property, header_data, context_name); return_statement_string = fmt::format(STR(" return {};"), default_property_value); } @@ -1017,9 +1022,9 @@ namespace RC::UEGenerator function_extra_postfix_string.append(fmt::format(STR(" PURE_VIRTUAL({},{})"), function->GetName(), return_statement_string)); } - std::wstring function_argument_list = generate_function_parameter_list(uclass, function, header_data, false, context_name, blacklisted_property_names); + StringType function_argument_list = generate_function_parameter_list(uclass, function, header_data, false, context_name, blacklisted_property_names); - const std::wstring function_flags_string = generate_function_flags(function, is_function_pure_virtual); + const StringType function_flags_string = generate_function_flags(function, is_function_pure_virtual); header_data.append_line(fmt::format(STR("UFUNCTION({})"), function_flags_string)); // Format for virtual functions // virtual () PURE_VIRTUAL(, ) @@ -1032,12 +1037,12 @@ namespace RC::UEGenerator header_data.append_line(STR("")); } - auto UEHeaderGenerator::generate_enum_value(UEnum* uenum, int64_t enum_value) -> std::wstring + auto UEHeaderGenerator::generate_enum_value(UEnum* uenum, int64_t enum_value) -> StringType { UEnum::ECppForm cpp_form = uenum->GetCppForm(); - const std::wstring enum_native_name = get_native_enum_name(uenum, false); + const StringType enum_native_name = get_native_enum_name(uenum, false); - std::wstring enum_constant_name; + StringType enum_constant_name; for (auto [Name, Value] : uenum->ForEachName()) { if (Value == enum_value) @@ -1064,12 +1069,12 @@ namespace RC::UEGenerator } auto UEHeaderGenerator::generate_simple_assignment_expression(FProperty* property, - const std::wstring& value, + const StringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& operator_type) -> void + const StringType& property_scope, + const StringType& operator_type) -> void { - const std::wstring field_class_name = property->GetName(); + const StringType field_class_name = property->GetName(); if (property->GetArrayDim() == 1) { implementation_file.append_line(fmt::format(STR("{}{}{}{};"), property_scope, field_class_name, operator_type, value)); @@ -1084,13 +1089,13 @@ namespace RC::UEGenerator } auto UEHeaderGenerator::generate_advanced_assignment_expression(FProperty* property, - const std::wstring& value, + const StringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& property_type, - const std::wstring& operator_type) -> void + const StringType& property_scope, + const StringType& property_type, + const StringType& operator_type) -> void { - const std::wstring field_class_name = property->GetName(); + const StringType field_class_name = property->GetName(); implementation_file.append_line(fmt::format(STR("const FProperty* p_{} = GetClass()->FindPropertyByName(\"{}\");"), field_class_name, field_class_name)); if (property->GetArrayDim() == 1) { @@ -1107,9 +1112,9 @@ namespace RC::UEGenerator } auto UEHeaderGenerator::generate_property_value( - UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const std::wstring& property_scope) -> void + UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const StringType& property_scope) -> void { - const std::wstring property_name = property->GetName(); + const StringType property_name = property->GetName(); if (property_name == STR("NativeClass") || property_name == STR("hudClass")) { return; } const bool private_access_modifier = get_property_access_modifier(property) == AccessModifier::Private; bool super_and_no_access = false; @@ -1117,7 +1122,7 @@ namespace RC::UEGenerator UStruct* super; void* super_object = nullptr; FProperty* super_property = nullptr; - const std::wstring property_type = generate_property_cxx_name(property, true, ustruct); + const StringType property_type = generate_property_cxx_name(property, true, ustruct); auto as_class = Cast(ustruct); if (as_class) { @@ -1125,7 +1130,7 @@ namespace RC::UEGenerator super_object = Cast(super)->GetClassDefaultObject(); if (super_object != nullptr) { - super_property = super->GetPropertyByNameInChain(property_name.data()); + super_property = super->GetPropertyByNameInChain(FromCharTypePtr(property_name.data())); } } else @@ -1135,7 +1140,7 @@ namespace RC::UEGenerator { super_object = malloc(super->GetPropertiesSize()); memset(super_object, 0, super->GetPropertiesSize()); - super_property = super->GetPropertyByNameInChain(property_name.data()); + super_property = super->GetPropertyByNameInChain(FromCharTypePtr(property_name.data())); } } @@ -1158,15 +1163,15 @@ namespace RC::UEGenerator } UEnum* uenum = byte_property->GetEnum(); - std::wstring result_property_value; + StringType result_property_value; if (uenum != NULL) { - const std::wstring enum_type_name = get_native_enum_name(uenum); + const StringType enum_type_name = get_native_enum_name(uenum); result_property_value = generate_enum_value(uenum, *byte_property_value); } else { - result_property_value = std::to_wstring(*byte_property_value); + result_property_value = ToStringFmt(*byte_property_value); } if (!super_and_no_access) @@ -1206,7 +1211,7 @@ namespace RC::UEGenerator } implementation_file.add_dependency_object(uenum, DependencyLevel::Include); - std::wstring result_property_value = generate_enum_value(uenum, value); + StringType result_property_value = generate_enum_value(uenum, value); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1248,7 +1253,7 @@ namespace RC::UEGenerator super_and_no_access = private_access_modifier; } - const std::wstring result_property_value = result_bool_value ? STR("true") : STR("false"); + const StringType result_property_value = result_bool_value ? STR("true") : STR("false"); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1266,13 +1271,13 @@ namespace RC::UEGenerator if (property->IsA()) { FName* name_value = property->ContainerPtrToValuePtr(object); - const std::wstring name_value_string = name_value->ToString(); + const StringType name_value_string = name_value->ToString(); // Ensure property either does not exist in parent class or is overriden in the CDO for the child class if (super_property != nullptr) { FName* super_name_value = super_property->ContainerPtrToValuePtr(super_object); - const std::wstring super_name_value_string = super_name_value->ToString(); + const StringType super_name_value_string = super_name_value->ToString(); if (name_value_string == super_name_value_string) { return; @@ -1282,7 +1287,7 @@ namespace RC::UEGenerator if (name_value_string != STR("None")) { - const std::wstring result_property_value = fmt::format(STR("TEXT(\"{}\")"), name_value_string); + const StringType result_property_value = fmt::format(STR("TEXT(\"{}\")"), name_value_string); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1299,13 +1304,13 @@ namespace RC::UEGenerator if (property->IsA()) { FString* string_value = property->ContainerPtrToValuePtr(object); - const std::wstring string_value_string = string_value->GetCharArray(); + const StringType string_value_string = string_value->GetCharArray(); // Ensure property either does not exist in parent class or is overriden in the CDO for the child class if (super_property != nullptr) { FString* super_string_value = super_property->ContainerPtrToValuePtr(super_object); - const std::wstring super_string_value_string = super_string_value->GetCharArray(); + const StringType super_string_value_string = super_string_value->GetCharArray(); if (string_value_string == super_string_value_string) { return; @@ -1315,7 +1320,7 @@ namespace RC::UEGenerator if (string_value_string != STR("")) { - const std::wstring result_value = create_string_literal(string_value_string); + const StringType result_value = create_string_literal(string_value_string); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_value, implementation_file, property_scope); @@ -1348,7 +1353,7 @@ namespace RC::UEGenerator if (text_value_string != STR("")) { - const std::wstring result_property_value = fmt::format(STR("FText::FromString({})"), create_string_literal(text_value_string)); + const StringType result_property_value = fmt::format(STR("FText::FromString({})"), create_string_literal(text_value_string)); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1396,8 +1401,8 @@ namespace RC::UEGenerator implementation_file.add_dependency_object(class_value, DependencyLevel::Include); // Otherwise, generate StaticClass call, assuming the class is native - const std::wstring object_class_name = get_native_class_name(class_value); - const std::wstring initializer = fmt::format(STR("{}::StaticClass()"), object_class_name); + const StringType object_class_name = get_native_class_name(class_value); + const StringType initializer = fmt::format(STR("{}::StaticClass()"), object_class_name); if (!super_and_no_access) { @@ -1454,14 +1459,14 @@ namespace RC::UEGenerator if (sub_object_value->HasAnyFlags(EObjectFlags::RF_DefaultSubObject)) { UClass* object_class_type = sub_object_value->GetClassPrivate(); - const std::wstring object_name = sub_object_value->GetName(); + const StringType object_name = sub_object_value->GetName(); UClass* super_object_class_type{}; // Additional checks to ensure this property needs to be initialized in the current class if (super_sub_object_value) { super_object_class_type = super_sub_object_value->GetClassPrivate(); - const std::wstring super_object_name = super_sub_object_value->GetName(); + const StringType super_object_name = super_sub_object_value->GetName(); if ((object_class_type == super_object_class_type) && (object_name == super_object_name)) { return; @@ -1470,7 +1475,7 @@ namespace RC::UEGenerator } bool parent_component_found = false; - std::wstring prior_property_variable{}; + StringType prior_property_variable{}; // Check to see if any other property in the super initialized a component with the same name to ensure // we are not creating the subobject in a child class unnecessarily. @@ -1484,7 +1489,7 @@ namespace RC::UEGenerator UObject* check_super_sub_object_value = *check_super_object_property->ContainerPtrToValuePtr(super_object); if (check_super_sub_object_value) { - std::wstring check_super_object_name = check_super_sub_object_value->GetName(); + StringType check_super_object_name = check_super_sub_object_value->GetName(); if (check_super_object_name == object_name) { parent_component_found = true; @@ -1497,17 +1502,17 @@ namespace RC::UEGenerator // Generate an initializer by either setting this property to a pre-existing property // overriding the object class of an existing component, or creating a new default subobject - std::wstring initializer{}; + StringType initializer{}; if (auto it = m_class_subobjects.find(object_name); it != m_class_subobjects.end()) { // Set property to equal previous property referencing the same object initializer = it->second; - FProperty* prior_property = ustruct->GetPropertyByNameInChain(initializer.c_str()); + FProperty* prior_property = ustruct->GetPropertyByNameInChain(FromCharTypePtr(initializer.c_str())); bool prior_private = get_property_access_modifier(prior_property) == AccessModifier::Private; if (prior_private) { UObject* check_sub_object_value = *prior_property->ContainerPtrToValuePtr(object); - std::wstring prior_prop_class_name = STR("NULL"); + StringType prior_prop_class_name = STR("NULL"); if (check_sub_object_value->GetClassPrivate() != nullptr) { prior_prop_class_name = get_native_class_name(check_sub_object_value->GetClassPrivate()); @@ -1539,7 +1544,7 @@ namespace RC::UEGenerator { // Generate a CreateDefaultSubobject function call implementation_file.add_dependency_object(object_class_type, DependencyLevel::Include); - const std::wstring object_class_name = get_native_class_name(object_class_type); + const StringType object_class_name = get_native_class_name(object_class_type); initializer = fmt::format(STR("CreateDefaultSubobject<{}>(TEXT(\"{}\"))"), object_class_name, object_name); m_class_subobjects.try_emplace(object_name, property->GetName()); if (!super_and_no_access) @@ -1552,7 +1557,7 @@ namespace RC::UEGenerator } } - FObjectProperty* attach_parent_property = static_cast(sub_object_value->GetPropertyByNameInChain(STR("AttachParent"))); + FObjectProperty* attach_parent_property = static_cast(sub_object_value->GetPropertyByNameInChain(FromCharTypePtr(STR("AttachParent")))); UObject* attach_parent_object_value{}; if (attach_parent_property) { @@ -1560,10 +1565,10 @@ namespace RC::UEGenerator } if (attach_parent_object_value != NULL) { - const std::wstring attach_parent_object_name = attach_parent_object_value->GetName(); - const std::wstring operator_type = STR("->"); + const StringType attach_parent_object_name = attach_parent_object_value->GetName(); + const StringType operator_type = STR("->"); bool parent_found = false; - std::wstring attach_string; + StringType attach_string; if (auto it = m_class_subobjects.find(attach_parent_object_name); it != m_class_subobjects.end()) { // Set property to equal previous property referencing the same object @@ -1580,7 +1585,7 @@ namespace RC::UEGenerator UObject* check_sub_object_value = *check_object_property->ContainerPtrToValuePtr(object); if (check_sub_object_value) { - std::wstring check_object_name = check_sub_object_value->GetName(); + StringType check_object_name = check_sub_object_value->GetName(); if (check_object_name == attach_parent_object_name) { if (get_property_access_modifier(check_object_property) != AccessModifier::Private) @@ -1640,8 +1645,8 @@ namespace RC::UEGenerator // Generate a ::StaticClass call if this object represents a class implementation_file.add_dependency_object(sub_object_as_class, DependencyLevel::Include); - const std::wstring object_class_name = get_native_class_name(sub_object_as_class); - const std::wstring initializer = fmt::format(STR("{}::StaticClass()"), object_class_name); + const StringType object_class_name = get_native_class_name(sub_object_as_class); + const StringType initializer = fmt::format(STR("{}::StaticClass()"), object_class_name); if (!super_and_no_access) { generate_simple_assignment_expression(property, initializer, implementation_file, property_scope); @@ -1670,7 +1675,7 @@ namespace RC::UEGenerator } void* StructDataPointer = StructProperty->container_ptr_to_value_ptr(Object); - const std::wstring NewPropertyScope = fmt::format(STR("{}{}."), PropertyScope, StructProperty->GetName()); + const StringType NewPropertyScope = fmt::format(STR("{}{}."), PropertyScope, StructProperty->GetName()); //Generate values for each struct property //TODO we do not really need to generate assignments for each struct member, we only really need members that are different from the constructor set @@ -1735,11 +1740,11 @@ namespace RC::UEGenerator super_and_no_access = private_access_modifier; } - std::wstring number_constant_string; + StringType number_constant_string; if (!numeric_property->IsFloatingPoint()) { int64 value = numeric_property->GetSignedIntPropertyValue(numeric_property->ContainerPtrToValuePtr(object)); - number_constant_string = std::to_wstring(value); + number_constant_string = ToStringFmt(value); } else { @@ -1764,13 +1769,13 @@ namespace RC::UEGenerator bool is_generating_interface, const CaseInsensitiveSet& blacklisted_property_names) -> void { - const std::wstring class_native_name = get_native_class_name(uclass, is_generating_interface); - const std::wstring raw_function_name = function->GetName(); + const StringType class_native_name = get_native_class_name(uclass, is_generating_interface); + const StringType raw_function_name = function->GetName(); auto function_flags = function->GetFunctionFlags(); PropertyTypeDeclarationContext context(uclass->GetName(), &implementation_file); - std::wstring function_implementation_name; - std::wstring net_validate_function_name; + StringType function_implementation_name; + StringType net_validate_function_name; bool is_input_function_const = ((function_flags)&FUNC_Const) != 0; if ((function_flags & FUNC_Net) != 0) @@ -1799,7 +1804,7 @@ namespace RC::UEGenerator function_implementation_name = fmt::format(STR("{}::{}"), class_native_name, raw_function_name); } - std::wstring function_parameter_list; + StringType function_parameter_list; if (!function_implementation_name.empty() || !net_validate_function_name.empty()) { function_parameter_list = @@ -1810,7 +1815,7 @@ namespace RC::UEGenerator { FProperty* return_value_property = function->GetReturnProperty(); - const std::wstring return_value_type = return_value_property ? generate_property_type_declaration(return_value_property, context) : STR("void"); + const StringType return_value_type = return_value_property ? generate_property_type_declaration(return_value_property, context) : STR("void"); implementation_file.append_line(fmt::format(STR("{} {}({}){} {{"), return_value_type, @@ -1821,7 +1826,7 @@ namespace RC::UEGenerator if (return_value_property != NULL) { - const std::wstring default_value = generate_default_property_value(return_value_property, implementation_file, context.context_name); + const StringType default_value = generate_default_property_value(return_value_property, implementation_file, context.context_name); implementation_file.append_line(fmt::format(STR("return {};"), default_value)); } @@ -1841,7 +1846,7 @@ namespace RC::UEGenerator } } - auto UEHeaderGenerator::generate_parameter_count_string(int32_t parameter_count) -> std::wstring + auto UEHeaderGenerator::generate_parameter_count_string(int32_t parameter_count) -> StringType { switch (parameter_count) { @@ -1929,15 +1934,15 @@ namespace RC::UEGenerator return AccessModifier::Public; } - auto UEHeaderGenerator::create_string_literal(const std::wstring& string) -> std::wstring + auto UEHeaderGenerator::create_string_literal(const StringType& string) -> StringType { - std::wstring result; + StringType result; result.append(STR("TEXT(\"")); bool previous_character_was_hex = false; - const wchar_t* ptr = string.c_str(); - while (wchar_t ch = *ptr++) + const CharType* ptr = string.c_str(); + while (CharType ch = *ptr++) { switch (ch) { @@ -1984,15 +1989,15 @@ namespace RC::UEGenerator return result; } - auto UEHeaderGenerator::convert_module_name_to_api_name(const std::wstring& module_name) -> std::wstring + auto UEHeaderGenerator::convert_module_name_to_api_name(const StringType& module_name) -> StringType { - std::wstring uppercase_string = string_to_uppercase(module_name); + StringType uppercase_string = string_to_uppercase(module_name); uppercase_string.append(STR("_API")); return uppercase_string; } - auto UEHeaderGenerator::add_module_and_sub_module_dependencies(std::set& out_module_dependencies, - const std::wstring& module_name, + auto UEHeaderGenerator::add_module_and_sub_module_dependencies(std::set& out_module_dependencies, + const StringType& module_name, bool add_self_module) -> void { // Prevent infinite recursion @@ -2008,7 +2013,7 @@ namespace RC::UEGenerator const auto iterator = m_module_dependencies.find(module_name); if (iterator != m_module_dependencies.end()) { - for (const std::wstring& DependencyModuleName : *iterator->second) + for (const StringType& DependencyModuleName : *iterator->second) { out_module_dependencies.insert(DependencyModuleName); } @@ -2047,7 +2052,7 @@ namespace RC::UEGenerator // TODO CannotImplementInterfaceInBlueprint is not exactly right, // TODO you can have interface with no implementable blueprint methods but that you can still implement in blueprint - auto UEHeaderGenerator::generate_interface_flags(UClass* uinterface) const -> std::wstring + auto UEHeaderGenerator::generate_interface_flags(UClass* uinterface) const -> StringType { FlagFormatHelper flag_format_helper{}; @@ -2084,7 +2089,7 @@ namespace RC::UEGenerator return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_class_flags(UClass* uclass) const -> std::wstring + auto UEHeaderGenerator::generate_class_flags(UClass* uclass) const -> StringType { FlagFormatHelper flag_format_helper{}; @@ -2218,7 +2223,7 @@ namespace RC::UEGenerator } } - const std::wstring class_config_name = uclass->GetClassConfigName().ToString(); + const StringType class_config_name = uclass->GetClassConfigName().ToString(); if (super_class == NULL || class_config_name != super_class->GetClassConfigName().ToString()) { flag_format_helper.add_parameter(STR("Config"), class_config_name); @@ -2266,10 +2271,10 @@ namespace RC::UEGenerator } /**/ - auto UEHeaderGenerator::generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> std::wstring + auto UEHeaderGenerator::generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> StringType { UClass* current_class = Unreal::Cast(property->GetOutermostOwner()); - const std::wstring field_class_name = property->GetClass().GetName(); + const StringType field_class_name = property->GetClass().GetName(); // Byte Property if (property->IsA()) @@ -2284,7 +2289,7 @@ namespace RC::UEGenerator context.source_file->add_dependency_object(enum_value, DependencyLevel::Include); } - const std::wstring enum_type_name = get_native_enum_name(enum_value); + const StringType enum_type_name = get_native_enum_name(enum_value); if ((property->GetPropertyFlags() & CPF_BlueprintVisible) != 0) { @@ -2311,14 +2316,14 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(uenum, DependencyLevel::Include); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const StringType enum_type_name = get_native_enum_name(uenum); if ((property->GetPropertyFlags() & CPF_BlueprintVisible) != 0) { this->m_blueprint_visible_enums.insert(enum_type_name); } - const std::wstring underlying_enum_type = generate_property_type_declaration(underlying_property, context); + const StringType underlying_enum_type = generate_property_type_declaration(underlying_property, context); this->m_underlying_enum_types.insert({enum_type_name, underlying_enum_type}); return enum_type_name; } @@ -2392,7 +2397,7 @@ namespace RC::UEGenerator context.source_file->add_dependency_object(meta_class, DependencyLevel::PreDeclaration); context.source_file->add_extra_include(STR("Templates/SubclassOf.h")); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const StringType meta_class_name = get_native_class_name(meta_class, false); return fmt::format(STR("TSubclassOf<{}>"), meta_class_name); } @@ -2417,7 +2422,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(meta_class, DependencyLevel::PreDeclaration); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const StringType meta_class_name = get_native_class_name(meta_class, false); return fmt::format(STR("TSoftClassPtr<{}>"), meta_class_name); } @@ -2438,7 +2443,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("{}*"), property_class_name); } @@ -2477,7 +2482,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TWeakObjectPtr<{}>"), property_class_name); } @@ -2496,7 +2501,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TLazyObjectPtr<{}>"), property_class_name); } @@ -2515,7 +2520,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const StringType property_class_name = get_native_class_name(property_class, false); return fmt::format(STR("TSoftObjectPtr<{}>"), property_class_name); } @@ -2535,7 +2540,7 @@ namespace RC::UEGenerator { context.source_file->add_dependency_object(interface_class, DependencyLevel::PreDeclaration); } - const std::wstring interface_class_name = get_native_class_name(interface_class, true); + const StringType interface_class_name = get_native_class_name(interface_class, true); return fmt::format(STR("TScriptInterface<{}>"), interface_class_name); } @@ -2550,7 +2555,7 @@ namespace RC::UEGenerator { throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const StringType native_struct_name = get_native_struct_name(script_struct); if (context.source_file != NULL) { @@ -2619,7 +2624,7 @@ namespace RC::UEGenerator if (property->IsA()) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); + const StringType property_class_name = field_path_property->GetPropertyClass()->GetName(); return fmt::format(STR("TFieldPath"), property_class_name); } @@ -2630,7 +2635,7 @@ namespace RC::UEGenerator FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - const std::wstring inner_property_type = generate_property_type_declaration(inner_property, context.inner_context()); + const StringType inner_property_type = generate_property_type_declaration(inner_property, context.inner_context()); return fmt::format(STR("TArray<{}>"), inner_property_type); } @@ -2639,7 +2644,7 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_type_declaration(element_prop, context.inner_context()); + const StringType element_property_type = generate_property_type_declaration(element_prop, context.inner_context()); return fmt::format(STR("TSet<{}>"), element_property_type); } @@ -2650,8 +2655,8 @@ namespace RC::UEGenerator FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - const std::wstring key_type = generate_property_type_declaration(key_property, context.inner_context()); - const std::wstring value_type = generate_property_type_declaration(value_property, context.inner_context()); + const StringType key_type = generate_property_type_declaration(key_property, context.inner_context()); + const StringType value_type = generate_property_type_declaration(value_property, context.inner_context()); return fmt::format(STR("TMap<{}, {}>"), key_type, value_type); } @@ -2675,7 +2680,7 @@ namespace RC::UEGenerator } //*/ - auto UEHeaderGenerator::generate_function_argument_flags(FProperty* property) const -> std::wstring + auto UEHeaderGenerator::generate_function_argument_flags(FProperty* property) const -> StringType { FlagFormatHelper flag_format_helper{}; auto property_flags = property->GetPropertyFlags(); @@ -2699,7 +2704,7 @@ namespace RC::UEGenerator return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_property_flags(FProperty* property) const -> std::wstring + auto UEHeaderGenerator::generate_property_flags(FProperty* property) const -> StringType { FlagFormatHelper flag_format_helper{}; auto property_flags = property->GetPropertyFlags(); @@ -2812,7 +2817,7 @@ namespace RC::UEGenerator { if ((property_flags & CPF_RepNotify) != 0) { - const std::wstring rep_notify_func_name = property->GetRepNotifyFunc().ToString(); + const StringType rep_notify_func_name = property->GetRepNotifyFunc().ToString(); flag_format_helper.add_parameter(STR("ReplicatedUsing"), rep_notify_func_name); } else @@ -2882,7 +2887,7 @@ namespace RC::UEGenerator return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_struct_flags(UScriptStruct* script_struct) const -> std::wstring + auto UEHeaderGenerator::generate_struct_flags(UScriptStruct* script_struct) const -> StringType { FlagFormatHelper flag_format_helper{}; @@ -2892,7 +2897,7 @@ namespace RC::UEGenerator EStructFlags struct_own_flags = (EStructFlags)(struct_flags & (~(parent_struct_flags & STRUCT_Inherit))); - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const StringType native_struct_name = get_native_struct_name(script_struct); if (is_struct_blueprint_type(script_struct) || m_blueprint_visible_structs.contains(native_struct_name) || UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllPropertyBlueprintsReadWrite) { @@ -2914,7 +2919,7 @@ namespace RC::UEGenerator return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_enum_flags(UEnum* uenum) const -> std::wstring + auto UEHeaderGenerator::generate_enum_flags(UEnum* uenum) const -> StringType { FlagFormatHelper flag_format_helper{}; @@ -2925,7 +2930,7 @@ namespace RC::UEGenerator { flag_format_helper.add_switch(STR("Flags")); } - const std::wstring enum_native_name = get_native_enum_name(uenum); + const StringType enum_native_name = get_native_enum_name(uenum); if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeEnumClassesBlueprintType) { @@ -2950,13 +2955,13 @@ namespace RC::UEGenerator return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::sanitize_enumeration_name(const std::wstring& enumeration_name) -> std::wstring + auto UEHeaderGenerator::sanitize_enumeration_name(const StringType& enumeration_name) -> StringType { - std::wstring result_enum_name = enumeration_name; + StringType result_enum_name = enumeration_name; // Remove enumeration name from the string size_t enum_name_string_split = enumeration_name.find(STR("::")); - if (enum_name_string_split != std::wstring::npos) + if (enum_name_string_split != StringType::npos) { result_enum_name.erase(0, enum_name_string_split + 2); } @@ -3007,7 +3012,7 @@ namespace RC::UEGenerator return lowest_enum_value; } - auto UEHeaderGenerator::generate_function_flags(UFunction* function, bool is_function_pure_virtual) const -> std::wstring + auto UEHeaderGenerator::generate_function_flags(UFunction* function, bool is_function_pure_virtual) const -> StringType { FlagFormatHelper flag_format_helper{}; @@ -3157,23 +3162,23 @@ namespace RC::UEGenerator UFunction* function, GeneratedSourceFile& header_data, bool generate_comma_before_name, - const std::wstring& context_name, + const StringType& context_name, const CaseInsensitiveSet& blacklisted_property_names, - int32_t* out_num_params) -> std::wstring + int32_t* out_num_params) -> StringType { - std::wstring function_arguments_string; + StringType function_arguments_string; for (FProperty* property : function->ForEachProperty()) { auto property_flags = property->GetPropertyFlags(); if ((property_flags & CPF_Parm) != 0 && (property_flags & CPF_ReturnParm) == 0) { - std::wstring param_declaration; + StringType param_declaration; // We only generate UPARAM declarations if we are not generating the implementation file if (!header_data.is_implementation_file()) { - const std::wstring parameter_flags_string = generate_function_argument_flags(property); + const StringType parameter_flags_string = generate_function_argument_flags(property); if (!parameter_flags_string.empty()) { param_declaration.append(STR("UPARAM(")); @@ -3209,7 +3214,7 @@ namespace RC::UEGenerator } param_declaration.append(STR(" ")); - std::wstring property_name = property->GetName(); + StringType property_name = property->GetName(); // If property name is blacklisted, capitalize first letter and prepend New if ((uclass && is_function_parameter_shadowing(uclass, property)) || blacklisted_property_names.contains(property_name)) @@ -3236,9 +3241,9 @@ namespace RC::UEGenerator return function_arguments_string; } - auto UEHeaderGenerator::generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const std::wstring& ContextName) -> std::wstring + auto UEHeaderGenerator::generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const StringType& ContextName) -> StringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const StringType field_class_name = property->GetClass().GetName(); PropertyTypeDeclarationContext context(ContextName, &header_data); // Byte Property @@ -3314,7 +3319,7 @@ namespace RC::UEGenerator { throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const StringType native_struct_name = get_native_struct_name(script_struct); return fmt::format(STR("{}{{}}"), native_struct_name); } @@ -3322,7 +3327,7 @@ namespace RC::UEGenerator if (field_class_name == STR("DelegateProperty") || field_class_name == STR("MulticastInlineDelegateProperty") || field_class_name == STR("MulticastSparseDelegateProperty")) { - const std::wstring delegate_type_name = generate_delegate_name(property, context.context_name); + const StringType delegate_type_name = generate_delegate_name(property, context.context_name); return fmt::format(STR("{}()"), delegate_type_name); } @@ -3338,7 +3343,7 @@ namespace RC::UEGenerator FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - const std::wstring inner_property_type = generate_property_type_declaration(inner_property, context); + const StringType inner_property_type = generate_property_type_declaration(inner_property, context); return fmt::format(STR("TArray<{}>()"), inner_property_type); } @@ -3347,7 +3352,7 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_type_declaration(element_prop, context); + const StringType element_property_type = generate_property_type_declaration(element_prop, context); return fmt::format(STR("TSet<{}>()"), element_property_type); } @@ -3357,8 +3362,8 @@ namespace RC::UEGenerator FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - const std::wstring key_type = generate_property_type_declaration(key_property, context); - const std::wstring value_type = generate_property_type_declaration(value_property, context); + const StringType key_type = generate_property_type_declaration(key_property, context); + const StringType value_type = generate_property_type_declaration(value_property, context); return fmt::format(STR("TMap<{}, {}>()"), key_type, value_type); } @@ -3468,18 +3473,18 @@ namespace RC::UEGenerator return is_shadowing; } - auto UEHeaderGenerator::get_module_name_for_package(UObject* package) -> std::wstring + auto UEHeaderGenerator::get_module_name_for_package(UObject* package) -> StringType { if (package->GetOuterPrivate() != NULL) { throw std::invalid_argument("Encountered a package with an outer object set"); } - std::wstring package_name = package->GetName(); + StringType package_name = package->GetName(); if (!package_name.starts_with(STR("/Script/"))) { return STR(""); } - package_name.erase(0, wcslen(STR("/Script/"))); + package_name.erase(0, sizeof("/Script/") - 1); return package_name; } @@ -3807,8 +3812,8 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_object_description_file(UObject* object) -> bool { - const std::wstring module_name = get_module_name_for_package(object->GetOutermost()); - const std::wstring file_base_name = get_header_name_for_object(object); + const StringType module_name = get_module_name_for_package(object->GetOutermost()); + const StringType file_base_name = get_header_name_for_object(object); if (module_name.empty()) { @@ -3866,7 +3871,7 @@ namespace RC::UEGenerator auto iterator = this->m_module_dependencies.find(module_name); if (iterator == this->m_module_dependencies.end()) { - iterator = this->m_module_dependencies.insert({module_name, std::make_shared>()}).first; + iterator = this->m_module_dependencies.insert({module_name, std::make_shared>()}).first; } if (!header_file.has_content_to_save()) @@ -3881,16 +3886,16 @@ namespace RC::UEGenerator header_file.generate_file_contents(); // Record module names used in the headers - std::shared_ptr> out_dependency_module_names = iterator->second; + std::shared_ptr> out_dependency_module_names = iterator->second; header_file.copy_dependency_module_names(*out_dependency_module_names); implementation_file.copy_dependency_module_names(*out_dependency_module_names); return true; } - auto UEHeaderGenerator::generate_object_pre_declaration(UObject* object) -> std::vector> + auto UEHeaderGenerator::generate_object_pre_declaration(UObject* object) -> std::vector> { - std::vector> pre_declarations; + std::vector> pre_declarations; UClass* object_class = object->GetClassPrivate(); @@ -3923,7 +3928,7 @@ namespace RC::UEGenerator return pre_declarations; } - auto UEHeaderGenerator::get_header_name_for_object(UObject* object, bool get_existing_header) -> std::wstring + auto UEHeaderGenerator::get_header_name_for_object(UObject* object, bool get_existing_header) -> StringType { File::StringType header_name{}; UObject* final_object{}; @@ -3958,7 +3963,7 @@ namespace RC::UEGenerator { // Otherwise, remove the postfix and use the function name as the header name // Also append the delegate postfix because apparently there can be conflicts - std::wstring DelegateName = strip_delegate_signature_postfix(signature_function); + StringType DelegateName = strip_delegate_signature_postfix(signature_function); DelegateName.append(STR("Delegate")); header_name = DelegateName; final_object = object; @@ -4000,18 +4005,18 @@ namespace RC::UEGenerator generate_delegate_type_declaration(signature_function, delegate_class, header_data); } - auto UEHeaderGenerator::determine_primary_game_module_name() -> std::wstring + auto UEHeaderGenerator::determine_primary_game_module_name() -> StringType { HMODULE primary_executable_module = GetModuleHandleW(NULL); - wchar_t module_name_buffer[1024]{'\0'}; - GetModuleFileNameW(primary_executable_module, module_name_buffer, ARRAYSIZE(module_name_buffer)); + CharType module_name_buffer[1024]{'\0'}; + GetModuleFileNameW(primary_executable_module, FromCharTypePtr(module_name_buffer), ARRAYSIZE(module_name_buffer)); // Retrieve the filename from the full path, strip down the extension - FFilePath root_executable_path((std::wstring(module_name_buffer))); - std::wstring filename = root_executable_path.filename().replace_extension().wstring(); + FFilePath root_executable_path((StringType(module_name_buffer))); + StringType filename = ensure_str(root_executable_path.filename().replace_extension()); // Remove the shipping file postfix - std::wstring shipping_postfix = STR("-Win64-Shipping"); + StringType shipping_postfix = STR("-Win64-Shipping"); if (filename.ends_with(shipping_postfix)) { filename.erase(filename.length() - shipping_postfix.length()); @@ -4019,7 +4024,7 @@ namespace RC::UEGenerator return filename; } - auto UEHeaderGenerator::generate_cross_module_include(UObject* object, const std::wstring& module_name, const std::wstring& fallback_name) -> std::wstring + auto UEHeaderGenerator::generate_cross_module_include(UObject* object, const StringType& module_name, const StringType& fallback_name) -> StringType { // Retrieve the most top level object located inside the native package UObject* top_level_object = object; @@ -4029,18 +4034,18 @@ namespace RC::UEGenerator top_level_object = top_level_object->GetOuterPrivate(); } - const std::wstring object_name = top_level_object->GetName(); + const StringType object_name = top_level_object->GetName(); return fmt::format(STR("//CROSS-MODULE INCLUDE V2: -ModuleName={} -ObjectName={} -FallbackName={}\n"), module_name, object_name, fallback_name); } GeneratedFile::GeneratedFile(const FFilePath& full_file_path) { this->m_full_file_path = full_file_path; - this->m_file_base_name = full_file_path.filename().replace_extension().wstring(); + this->m_file_base_name = ensure_str(full_file_path.filename().replace_extension()); this->m_current_indent_count = 0; } - auto GeneratedFile::append_line(const std::wstring& line) -> void + auto GeneratedFile::append_line(const StringType& line) -> void { for (int32_t i = 0; i < m_current_indent_count; i++) { @@ -4050,7 +4055,7 @@ namespace RC::UEGenerator m_file_contents_buffer.append(STR("\n")); } - auto GeneratedFile::append_line_no_indent(const std::wstring& line) -> void + auto GeneratedFile::append_line_no_indent(const StringType& line) -> void { m_file_contents_buffer.append(line); m_file_contents_buffer.append(STR("\n")); @@ -4079,7 +4084,7 @@ namespace RC::UEGenerator // TODO might be slow, maybe move it out into the header generator? std::filesystem::create_directories(this->m_full_file_path.parent_path()); - std::wofstream file_output_stream; + std::basic_ofstream file_output_stream; file_output_stream.open(m_full_file_path); if (!file_output_stream.is_open()) { @@ -4090,7 +4095,7 @@ namespace RC::UEGenerator return true; } - auto GeneratedFile::generate_file_contents() -> std::wstring + auto GeneratedFile::generate_file_contents() -> StringType { return m_file_contents_buffer; } @@ -4101,8 +4106,8 @@ namespace RC::UEGenerator } auto GeneratedSourceFile::create_source_file(const FFilePath& root_dir, - const std::wstring& module_name, - const std::wstring& base_name, + const StringType& module_name, + const StringType& base_name, bool is_implementation_file, UObject* object) -> GeneratedSourceFile { @@ -4118,7 +4123,7 @@ namespace RC::UEGenerator return GeneratedSourceFile(full_file_path, module_name, is_implementation_file, object); } - GeneratedSourceFile::GeneratedSourceFile(const FFilePath& file_path, const std::wstring& file_module_name, bool is_implementation_file, UObject* object) + GeneratedSourceFile::GeneratedSourceFile(const FFilePath& file_path, const StringType& file_module_name, bool is_implementation_file, UObject* object) : GeneratedFile(file_path) { this->m_file_module_name = file_module_name; @@ -4131,7 +4136,7 @@ namespace RC::UEGenerator this->m_header_file = header_file; } - auto GeneratedSourceFile::add_extra_include(const std::wstring& included_file_name) -> void + auto GeneratedSourceFile::add_extra_include(const StringType& included_file_name) -> void { this->m_extra_includes.insert(included_file_name); } @@ -4147,13 +4152,13 @@ namespace RC::UEGenerator } } - auto GeneratedSourceFile::generate_file_contents() -> std::wstring + auto GeneratedSourceFile::generate_file_contents() -> StringType { - std::wstring result_header_contents; + StringType result_header_contents; result_header_contents.append(generate_includes_string()); result_header_contents.append(STR("\n")); - std::wstring pre_declarations_string = generate_pre_declarations_string(); + StringType pre_declarations_string = generate_pre_declarations_string(); if (!pre_declarations_string.empty()) { result_header_contents.append(pre_declarations_string); @@ -4174,11 +4179,11 @@ namespace RC::UEGenerator return result_header_contents; } - auto GeneratedSourceFile::generate_includes_string() const -> std::wstring + auto GeneratedSourceFile::generate_includes_string() const -> StringType { - std::wstring result_include_string; - std::vector> include_lines; - std::vector cross_module_includes; + StringType result_include_string; + std::vector> include_lines; + std::vector cross_module_includes; // For the header file, we generate the pragma and minimal core includes if (!m_is_implementation_file) @@ -4202,7 +4207,7 @@ namespace RC::UEGenerator } // Generate extra includes we might need that do not represent objects - for (const std::wstring& extra_included_file : m_extra_includes) + for (const StringType& extra_included_file : m_extra_includes) { include_lines.push_back({STR("#include \""), extra_included_file, STR("\"\n")}); } @@ -4218,7 +4223,7 @@ namespace RC::UEGenerator continue; } - const std::wstring object_header_name = UEHeaderGenerator::get_header_name_for_object(dependency_object, true); + const StringType object_header_name = UEHeaderGenerator::get_header_name_for_object(dependency_object, true); // Definitely skip include if object in question is placed into this header if (object_header_name == m_file_base_name) @@ -4235,7 +4240,7 @@ namespace RC::UEGenerator } } UObject* package = dependency_object->GetOutermost(); - std::wstring native_module_name = UEHeaderGenerator::get_module_name_for_package(package); + StringType native_module_name = UEHeaderGenerator::get_module_name_for_package(package); if (!native_module_name.empty()) { @@ -4260,13 +4265,13 @@ namespace RC::UEGenerator // Remove duplicates - there are sometimes multiple instances of the same cross module include cross_module_includes.erase(std::unique(cross_module_includes.begin(), cross_module_includes.end()), cross_module_includes.end()); - for (const std::wstring& cross_module_include : cross_module_includes) + for (const StringType& cross_module_include : cross_module_includes) { result_include_string.append(cross_module_include); } // Sort the includes by module name, since we want to make sure that they are always in the same order - std::sort(include_lines.begin(), include_lines.end(), [](const std::vector& a, const std::vector& b) { + std::sort(include_lines.begin(), include_lines.end(), [](const std::vector& a, const std::vector& b) { return a[1] < b[1]; }); @@ -4286,10 +4291,10 @@ namespace RC::UEGenerator return result_include_string; } - auto GeneratedSourceFile::generate_pre_declarations_string() const -> std::wstring + auto GeneratedSourceFile::generate_pre_declarations_string() const -> StringType { - std::wstring result_declarations; - std::vector>> pre_declarations; + StringType result_declarations; + std::vector>> pre_declarations; // Generate pre-declarations for the relevant object files for (const auto& dependency_pair : m_dependencies) @@ -4304,7 +4309,7 @@ namespace RC::UEGenerator // We still need to reference the object's owner module UObject* package = dependency_object->GetOutermost(); - std::wstring native_module_name = UEHeaderGenerator::get_module_name_for_package(package); + StringType native_module_name = UEHeaderGenerator::get_module_name_for_package(package); if (!native_module_name.empty() && m_file_module_name != native_module_name) { @@ -4317,7 +4322,7 @@ namespace RC::UEGenerator // Sort the entries alphabetically by the class name std::sort(pre_declarations.begin(), pre_declarations.end(), - [](const std::vector>& a, const std::vector>& b) { + [](const std::vector>& a, const std::vector>& b) { return a[0][1] < b[0][1]; }); diff --git a/UE4SS/src/Signatures.cpp b/UE4SS/src/Signatures.cpp index 147feec75..21e6cd985 100644 --- a/UE4SS/src/Signatures.cpp +++ b/UE4SS/src/Signatures.cpp @@ -12,13 +12,15 @@ #include #include +#include + namespace RC { auto scan_complete_default_func(DidLuaScanSucceed) -> void { } - auto scan_from_lua_script(std::wstring& script_file_path_and_name, + auto scan_from_lua_script(std::filesystem::path& script_file_path_and_name, std::vector& signature_containers, LuaScriptMatchFoundFunc& match_found_func, LuaScriptScanCompleteFunc& scan_complete_func) -> void @@ -31,14 +33,14 @@ namespace RC lua.register_function("DerefToInt32", LuaLibrary::deref_to_int32); lua.register_function("dereftoint32", LuaLibrary::deref_to_int32); - lua.execute_file(script_file_path_and_name); + lua.execute_file(script_file_path_and_name.string()); constexpr const char* global_register_func_name = "Register"; constexpr const char* global_on_match_found_func_name = "OnMatchFound"; if (!lua.is_global_function(global_register_func_name) || !lua.is_global_function(global_on_match_found_func_name)) { - Output::send(STR("Lua functions 'Register' and 'OnMatchFound' must be present in {}\n"), script_file_path_and_name); + Output::send(STR("Lua functions 'Register' and 'OnMatchFound' must be present in {}\n"), ensure_str(script_file_path_and_name)); throw std::runtime_error{"See error message above"}; } @@ -91,7 +93,7 @@ namespace RC auto setup_lua_scan_overrides(std::filesystem::path& working_directory, Unreal::UnrealInitializer::Config& config) -> void { - std::wstring lua_guobjectarray_scan_script = working_directory / "UE4SS_Signatures/GUObjectArray.lua"; + auto lua_guobjectarray_scan_script = working_directory / "UE4SS_Signatures/GUObjectArray.lua"; if (std::filesystem::exists(lua_guobjectarray_scan_script)) { config.ScanOverrides.guobjectarray = [lua_guobjectarray_scan_script](std::vector& signature_containers, @@ -113,7 +115,7 @@ namespace RC }; } - std::wstring lua_fts_scan_script = working_directory / "UE4SS_Signatures/FName_ToString.lua"; + auto lua_fts_scan_script = working_directory / "UE4SS_Signatures/FName_ToString.lua"; if (std::filesystem::exists(lua_fts_scan_script)) { config.ScanOverrides.fname_to_string = [lua_fts_scan_script](std::vector& signature_containers, @@ -135,7 +137,7 @@ namespace RC }; } - std::wstring lua_fnc_scan_script = working_directory / "UE4SS_Signatures/FName_Constructor.lua"; + auto lua_fnc_scan_script = working_directory / "UE4SS_Signatures/FName_Constructor.lua"; if (std::filesystem::exists(lua_fnc_scan_script)) { config.ScanOverrides.fname_constructor = [lua_fnc_scan_script](std::vector& signature_containers, @@ -144,9 +146,9 @@ namespace RC lua_fnc_scan_script, signature_containers, [&scan_result](void* address) { - Unreal::FName name = Unreal::FName(L"bCanBeDamaged", Unreal::FNAME_Find, address); + Unreal::FName name = Unreal::FName(STR("bCanBeDamaged"), Unreal::FNAME_Find, address); - if (name == L"bCanBeDamaged") + if (name == STR("bCanBeDamaged")) { Output::send(STR("FName::FName address: {} <- Lua Script\n"), address); Unreal::FName::ConstructorInternal.assign_address(address); @@ -168,8 +170,8 @@ namespace RC } // For compatibility, we look for 'FMemory_Free.lua' if 'GMalloc.lua' doesn't exist. - std::wstring lua_ffree_scan_script_new = working_directory / "UE4SS_Signatures/GMalloc.lua"; - std::wstring lua_ffree_scan_script_compat = working_directory / "UE4SS_Signatures/FMemory_Free.lua"; + auto lua_ffree_scan_script_new = working_directory / "UE4SS_Signatures/GMalloc.lua"; + auto lua_ffree_scan_script_compat = working_directory / "UE4SS_Signatures/FMemory_Free.lua"; auto lua_ffree_scan_script = std::filesystem::exists(lua_ffree_scan_script_new) ? lua_ffree_scan_script_new : lua_ffree_scan_script_compat; if (std::filesystem::exists(lua_ffree_scan_script)) { @@ -193,7 +195,7 @@ namespace RC }; } - std::wstring lua_sco_scan_script = working_directory / "UE4SS_Signatures/StaticConstructObject.lua"; + auto lua_sco_scan_script = working_directory / "UE4SS_Signatures/StaticConstructObject.lua"; if (std::filesystem::exists(lua_sco_scan_script)) { config.ScanOverrides.static_construct_object = [lua_sco_scan_script](std::vector& signature_containers, @@ -215,7 +217,7 @@ namespace RC }; } - std::wstring lua_ftc_scan_script = working_directory / "UE4SS_Signatures/FText_Constructor.lua"; + auto lua_ftc_scan_script = working_directory / "UE4SS_Signatures/FText_Constructor.lua"; if (std::filesystem::exists(lua_ftc_scan_script)) { config.ScanOverrides.ftext_constructor = [lua_ftc_scan_script](std::vector& signature_containers, @@ -224,9 +226,9 @@ namespace RC lua_ftc_scan_script, signature_containers, [&scan_result](void* address) { - Unreal::FText text = Unreal::FText(L"bCanBeDamaged", address); + Unreal::FText text = Unreal::FText(STR("bCanBeDamaged"), address); - if (text == L"bCanBeDamaged") + if (text == STR("bCanBeDamaged")) { Output::send(STR("FText::FText address: {} <- Lua Script\n"), address); Unreal::FText::ConstructorInternal.assign_address(address); diff --git a/UE4SS/src/UE4SSProgram.cpp b/UE4SS/src/UE4SSProgram.cpp index 2c613cb83..785b8eb97 100644 --- a/UE4SS/src/UE4SSProgram.cpp +++ b/UE4SS/src/UE4SSProgram.cpp @@ -133,7 +133,7 @@ namespace RC { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_a, &LoadLibraryA)(dll_name); - program.fire_dll_load_for_cpp_mods(to_wstring(dll_name)); + program.fire_dll_load_for_cpp_mods(ensure_str(dll_name)); return lib; } @@ -141,7 +141,7 @@ namespace RC { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_ex_a, &LoadLibraryExA)(dll_name, file, flags); - program.fire_dll_load_for_cpp_mods(to_wstring(dll_name)); + program.fire_dll_load_for_cpp_mods(ensure_str(dll_name)); return lib; } @@ -149,7 +149,7 @@ namespace RC { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_w, &LoadLibraryW)(dll_name); - program.fire_dll_load_for_cpp_mods(dll_name); + program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name)); return lib; } @@ -157,11 +157,11 @@ namespace RC { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_ex_w, &LoadLibraryExW)(dll_name, file, flags); - program.fire_dll_load_for_cpp_mods(dll_name); + program.fire_dll_load_for_cpp_mods(ToCharTypePtr(dll_name)); return lib; } - UE4SSProgram::UE4SSProgram(const std::wstring& moduleFilePath, std::initializer_list options) : MProgram(options) + UE4SSProgram::UE4SSProgram(const std::filesystem::path& moduleFilePath, std::initializer_list options) : MProgram(options) { ProfilerScope(); s_program = this; @@ -176,7 +176,7 @@ namespace RC } catch (std::exception& e) { - create_emergency_console_for_early_error(fmt::format(STR("The IniParser failed to parse: {}"), to_wstring(e.what()))); + create_emergency_console_for_early_error(fmt::format(STR("The IniParser failed to parse: {}"), ensure_str(e.what()))); return; } @@ -191,7 +191,7 @@ namespace RC // Setup the log file auto& file_device = Output::set_default_devices(); - file_device.set_file_name_and_path(m_log_directory / m_log_file_name); + file_device.set_file_name_and_path(ensure_str((m_log_directory / m_log_file_name))); create_simple_console(); @@ -221,18 +221,18 @@ namespace RC UE4SS_LIB_VERSION_MAJOR, UE4SS_LIB_VERSION_MINOR, UE4SS_LIB_VERSION_HOTFIX, - fmt::format(L"{}", UE4SS_LIB_VERSION_PRERELEASE == 0 ? L"" : fmt::format(L" PreRelease #{}", UE4SS_LIB_VERSION_PRERELEASE)), - fmt::format(L"{}", - UE4SS_LIB_BETA_STARTED == 0 ? L"" : (UE4SS_LIB_IS_BETA == 0 ? L" Beta #?" : fmt::format(L" Beta #{}", UE4SS_LIB_VERSION_BETA))), - to_wstring(UE4SS_LIB_BUILD_GITSHA)); + fmt::format(STR("{}"), UE4SS_LIB_VERSION_PRERELEASE == 0 ? STR("") : fmt::format(STR(" PreRelease #{}"), UE4SS_LIB_VERSION_PRERELEASE)), + fmt::format(STR("{}"), + UE4SS_LIB_BETA_STARTED == 0 ? STR("") : (UE4SS_LIB_IS_BETA == 0 ? STR(" Beta #?") : fmt::format(STR(" Beta #{}"), UE4SS_LIB_VERSION_BETA))), + ensure_str(UE4SS_LIB_BUILD_GITSHA)); #ifdef __clang__ -#define UE4SS_COMPILER L"Clang" +#define UE4SS_COMPILER STR("Clang") #else -#define UE4SS_COMPILER L"MSVC" +#define UE4SS_COMPILER STR("MSVC") #endif - Output::send(STR("UE4SS Build Configuration: {} ({})\n"), to_wstring(UE4SS_CONFIGURATION), UE4SS_COMPILER); + Output::send(STR("UE4SS Build Configuration: {} ({})\n"), ensure_str(UE4SS_CONFIGURATION), UE4SS_COMPILER); m_load_library_a_hook = std::make_unique("kernel32.dll", "LoadLibraryA", @@ -272,21 +272,21 @@ namespace RC if (m_has_game_specific_config) { - Output::send(STR("Found configuration for game: {}\n"), m_mods_directory.parent_path().filename().c_str()); + Output::send(STR("Found configuration for game: {}\n"), ensure_str(m_mods_directory.parent_path().filename())); } else { Output::send(STR("No specific game configuration found, using default configuration file\n")); } - Output::send(STR("Config: {}\n\n"), m_settings_path_and_file.c_str()); - Output::send(STR("root directory: {}\n"), m_root_directory.c_str()); - Output::send(STR("working directory: {}\n"), m_working_directory.c_str()); - Output::send(STR("game executable directory: {}\n"), m_game_executable_directory.c_str()); - Output::send(STR("game executable: {} ({} bytes)\n\n\n"), m_game_path_and_exe_name.c_str(), std::filesystem::file_size(m_game_path_and_exe_name)); - Output::send(STR("mods directory: {}\n"), m_mods_directory.c_str()); - Output::send(STR("log directory: {}\n"), m_log_directory.c_str()); - Output::send(STR("object dumper directory: {}\n\n\n"), m_object_dumper_output_directory.c_str()); + Output::send(STR("Config: {}\n\n"), ensure_str(m_settings_path_and_file)); + Output::send(STR("root directory: {}\n"), ensure_str(m_root_directory)); + Output::send(STR("working directory: {}\n"), ensure_str(m_working_directory)); + Output::send(STR("game executable directory: {}\n"), ensure_str(m_game_executable_directory)); + Output::send(STR("game executable: {} ({} bytes)\n\n\n"), ensure_str(m_game_path_and_exe_name), std::filesystem::file_size(m_game_path_and_exe_name)); + Output::send(STR("mods directory: {}\n"), ensure_str(m_mods_directory)); + Output::send(STR("log directory: {}\n"), ensure_str(m_log_directory)); + Output::send(STR("object dumper directory: {}\n\n\n"), ensure_str(m_object_dumper_output_directory)); } catch (std::runtime_error& e) { @@ -329,7 +329,7 @@ namespace RC // only log modules with unique addresses (non-modular builds have everything in MainExe) if (i == static_cast(ScanTarget::MainExe) || main_exe_ptr != module.lpBaseOfDll) { - auto module_name = to_wstring(ScanTargetToString(i)); + auto module_name = ensure_str(ScanTargetToString(i)); Output::send(STR("{} @ {} size={:#x}\n"), module_name.c_str(), module.lpBaseOfDll, module.SizeOfImage); } } @@ -367,12 +367,11 @@ namespace RC } } - auto UE4SSProgram::setup_paths(const std::wstring& moduleFilePathString) -> void + auto UE4SSProgram::setup_paths(const std::filesystem::path& moduleFilePath) -> void { ProfilerScope(); - const std::filesystem::path moduleFilePath = std::filesystem::path(moduleFilePathString); - m_root_directory = moduleFilePath.parent_path().wstring(); - m_module_file_path = moduleFilePath.wstring(); + m_root_directory = moduleFilePath.parent_path(); + m_module_file_path = moduleFilePath; // The default working directory is the root directory // Can be changed by creating a directory in the root directory @@ -406,7 +405,7 @@ namespace RC { m_has_game_specific_config = true; m_working_directory = item.path(); - m_mods_directory = item.path().wstring() + L"\\Mods"; + m_mods_directory = item.path() / STR("Mods"); m_settings_path_and_file = std::move(item.path()); m_log_directory = m_working_directory; m_object_dumper_output_directory = m_working_directory; @@ -433,7 +432,7 @@ namespace RC { settings_manager.Debug.SimpleConsoleEnabled = true; create_simple_console(); - printf_s("%S\n", error_message.data()); + printf_s("%S\n", FromCharTypePtr(error_message.data())); } auto UE4SSProgram::setup_mod_directory_path() -> void @@ -501,7 +500,7 @@ namespace RC { ProfilerScope(); // Retrieve offsets from the config file - const std::wstring offset_overrides_section{L"OffsetOverrides"}; + const StringType offset_overrides_section{STR("OffsetOverrides")}; load_unreal_offsets_from_file(); @@ -569,7 +568,7 @@ namespace RC // Virtual function offset overrides TRY([&]() { ProfilerScopeNamed("loading virtual function offset overrides"); - static File::StringType virtual_function_offset_override_file{(m_working_directory / STR("VTableLayout.ini")).wstring()}; + static File::StringType virtual_function_offset_override_file{ensure_str((m_working_directory / STR("VTableLayout.ini")))}; if (std::filesystem::exists(virtual_function_offset_override_file)) { auto file = @@ -959,28 +958,28 @@ namespace RC auto UE4SSProgram::setup_unreal_properties() -> void { - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ObjectProperty").GetComparisonIndex(), &LuaType::push_objectproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ClassProperty").GetComparisonIndex(), &LuaType::push_classproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int8Property").GetComparisonIndex(), &LuaType::push_int8property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int16Property").GetComparisonIndex(), &LuaType::push_int16property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"IntProperty").GetComparisonIndex(), &LuaType::push_intproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int64Property").GetComparisonIndex(), &LuaType::push_int64property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ByteProperty").GetComparisonIndex(), &LuaType::push_byteproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt16Property").GetComparisonIndex(), &LuaType::push_uint16property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt32Property").GetComparisonIndex(), &LuaType::push_uint32property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt64Property").GetComparisonIndex(), &LuaType::push_uint64property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"StructProperty").GetComparisonIndex(), &LuaType::push_structproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ArrayProperty").GetComparisonIndex(), &LuaType::push_arrayproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"FloatProperty").GetComparisonIndex(), &LuaType::push_floatproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"DoubleProperty").GetComparisonIndex(), &LuaType::push_doubleproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"BoolProperty").GetComparisonIndex(), &LuaType::push_boolproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"EnumProperty").GetComparisonIndex(), &LuaType::push_enumproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"WeakObjectProperty").GetComparisonIndex(), &LuaType::push_weakobjectproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"NameProperty").GetComparisonIndex(), &LuaType::push_nameproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"TextProperty").GetComparisonIndex(), &LuaType::push_textproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"StrProperty").GetComparisonIndex(), &LuaType::push_strproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"SoftClassProperty").GetComparisonIndex(), &LuaType::push_softclassproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"InterfaceProperty").GetComparisonIndex(), &LuaType::push_interfaceproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ObjectProperty")).GetComparisonIndex(), &LuaType::push_objectproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ClassProperty")).GetComparisonIndex(), &LuaType::push_classproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int8Property")).GetComparisonIndex(), &LuaType::push_int8property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int16Property")).GetComparisonIndex(), &LuaType::push_int16property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("IntProperty")).GetComparisonIndex(), &LuaType::push_intproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int64Property")).GetComparisonIndex(), &LuaType::push_int64property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ByteProperty")).GetComparisonIndex(), &LuaType::push_byteproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt16Property")).GetComparisonIndex(), &LuaType::push_uint16property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt32Property")).GetComparisonIndex(), &LuaType::push_uint32property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt64Property")).GetComparisonIndex(), &LuaType::push_uint64property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("StructProperty")).GetComparisonIndex(), &LuaType::push_structproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ArrayProperty")).GetComparisonIndex(), &LuaType::push_arrayproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("FloatProperty")).GetComparisonIndex(), &LuaType::push_floatproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("DoubleProperty")).GetComparisonIndex(), &LuaType::push_doubleproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("BoolProperty")).GetComparisonIndex(), &LuaType::push_boolproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("EnumProperty")).GetComparisonIndex(), &LuaType::push_enumproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("WeakObjectProperty")).GetComparisonIndex(), &LuaType::push_weakobjectproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("NameProperty")).GetComparisonIndex(), &LuaType::push_nameproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("TextProperty")).GetComparisonIndex(), &LuaType::push_textproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("StrProperty")).GetComparisonIndex(), &LuaType::push_strproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("SoftClassProperty")).GetComparisonIndex(), &LuaType::push_softclassproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("InterfaceProperty")).GetComparisonIndex(), &LuaType::push_interfaceproperty); } auto UE4SSProgram::setup_mods() -> void @@ -1008,10 +1007,10 @@ namespace RC set_error("is_directory ran into error %d", ec.value()); } - std::wstring directory_lowercase = sub_directory.path().stem().wstring(); + StringType directory_lowercase = ensure_str(sub_directory.path().stem()); std::transform(directory_lowercase.begin(), directory_lowercase.end(), directory_lowercase.begin(), std::towlower); - if (directory_lowercase == L"shared") + if (directory_lowercase == STR("shared")) { // Do stuff when shared libraries have been implemented } @@ -1019,9 +1018,9 @@ namespace RC { // Create the mod but don't install it yet if (std::filesystem::exists(sub_directory.path() / "scripts")) - m_mods.emplace_back(std::make_unique(*this, sub_directory.path().stem().wstring(), sub_directory.path().wstring())); + m_mods.emplace_back(std::make_unique(*this, ensure_str(sub_directory.path().stem()), ensure_str(sub_directory.path()))); if (std::filesystem::exists(sub_directory.path() / "dlls")) - m_mods.emplace_back(std::make_unique(*this, sub_directory.path().stem().wstring(), sub_directory.path().wstring())); + m_mods.emplace_back(std::make_unique(*this, ensure_str(sub_directory.path().stem()), ensure_str(sub_directory.path()))); } } } @@ -1113,7 +1112,7 @@ namespace RC } } - auto UE4SSProgram::fire_dll_load_for_cpp_mods(std::wstring_view dll_name) -> void + auto UE4SSProgram::fire_dll_load_for_cpp_mods(StringViewType dll_name) -> void { for (const auto& mod : m_mods) { @@ -1140,13 +1139,13 @@ namespace RC else { // 'mods.txt' exists, lets parse it - std::wifstream mods_stream{enabled_mods_file}; + StreamIType mods_stream{enabled_mods_file}; - std::wstring current_line; + StringType current_line; while (std::getline(mods_stream, current_line)) { // Don't parse any lines with ';' - if (current_line.find(L";") != current_line.npos) + if (current_line.find(STR(";")) != current_line.npos) { continue; } @@ -1158,12 +1157,12 @@ namespace RC } // Remove all spaces - auto end = std::remove(current_line.begin(), current_line.end(), L' '); + auto end = std::remove(current_line.begin(), current_line.end(), STR(' ')); current_line.erase(end, current_line.end()); // Parse the line into something that can be converted into proper data - std::wstring mod_name = explode_by_occurrence(current_line, L':', 1); - std::wstring mod_enabled = explode_by_occurrence(current_line, L':', ExplodeType::FromEnd); + StringType mod_name = explode_by_occurrence(current_line, STR(':'), 1); + StringType mod_enabled = explode_by_occurrence(current_line, STR(':'), ExplodeType::FromEnd); auto mod = UE4SSProgram::find_mod_by_name(mod_name, UE4SSProgram::IsInstalled::Yes); if (!mod || !dynamic_cast(mod)) @@ -1171,7 +1170,7 @@ namespace RC continue; } - if (!mod_enabled.empty() && mod_enabled[0] == L'1') + if (!mod_enabled.empty() && mod_enabled[0] == STR('1')) { Output::send(STR("Starting {} mod '{}'\n"), std::is_same_v ? STR("Lua") : STR("C++"), mod->get_name().data()); mod->start_mod(); @@ -1208,7 +1207,7 @@ namespace RC return fmt::format("exists ran into error {}", ec.value()); } - auto mod = UE4SSProgram::find_mod_by_name(mod_directory.path().stem().c_str(), UE4SSProgram::IsInstalled::Yes); + auto mod = UE4SSProgram::find_mod_by_name(ensure_str(mod_directory.path().stem()), UE4SSProgram::IsInstalled::Yes); if (!dynamic_cast(mod)) { continue; @@ -1358,29 +1357,29 @@ namespace RC Output::send(STR("All mods re-installed\n")); } - auto UE4SSProgram::get_module_directory() -> File::StringViewType + auto UE4SSProgram::get_module_directory() -> File::StringType { - return m_module_file_path.c_str(); + return ensure_str(m_module_file_path); } - auto UE4SSProgram::get_game_executable_directory() -> File::StringViewType + auto UE4SSProgram::get_game_executable_directory() -> File::StringType { - return m_game_executable_directory.c_str(); + return ensure_str(m_game_executable_directory); } - auto UE4SSProgram::get_working_directory() -> File::StringViewType + auto UE4SSProgram::get_working_directory() -> File::StringType { - return m_working_directory.c_str(); + return ensure_str(m_working_directory); } - auto UE4SSProgram::get_mods_directory() -> File::StringViewType + auto UE4SSProgram::get_mods_directory() -> File::StringType { - return m_mods_directory.c_str(); + return ensure_str(m_mods_directory); } - auto UE4SSProgram::get_legacy_root_directory() -> File::StringViewType + auto UE4SSProgram::get_legacy_root_directory() -> File::StringType { - return m_legacy_root_directory.c_str(); + return ensure_str(m_legacy_root_directory); } auto UE4SSProgram::generate_uht_compatible_headers() -> void @@ -1519,7 +1518,7 @@ namespace RC return m_input_handler.is_keydown_event_registered(key, modifier_keys); } - auto UE4SSProgram::find_mod_by_name_internal(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started, FMBNI_ExtraPredicate extra_predicate) + auto UE4SSProgram::find_mod_by_name_internal(StringViewType mod_name, IsInstalled is_installed, IsStarted is_started, FMBNI_ExtraPredicate extra_predicate) -> Mod* { auto mod_exists_with_name = std::find_if(get_program().m_mods.begin(), get_program().m_mods.end(), [&](auto& elem) -> bool { @@ -1562,14 +1561,14 @@ namespace RC return static_cast(find_mod_by_name(mod_name, installed_only, is_started)); } - auto UE4SSProgram::find_lua_mod_by_name(std::wstring_view mod_name, UE4SSProgram::IsInstalled installed_only, IsStarted is_started) -> LuaMod* + auto UE4SSProgram::find_lua_mod_by_name(StringViewType mod_name, UE4SSProgram::IsInstalled installed_only, IsStarted is_started) -> LuaMod* { return static_cast(find_mod_by_name(mod_name, installed_only, is_started)); } auto UE4SSProgram::get_object_dumper_output_directory() -> const File::StringType { - return m_object_dumper_output_directory.c_str(); + return ensure_str(m_object_dumper_output_directory); } auto UE4SSProgram::dump_uobject(UObject* object, std::unordered_set* in_dumped_fields, StringType& out_line, bool is_below_425) -> void @@ -1606,7 +1605,7 @@ namespace RC // Dump UObject ObjectDumper::get_to_string(typed_class)(object, out_line); - out_line.append(L"\n"); + out_line.append(STR("\n")); if (!is_below_425 && ObjectDumper::to_string_complex_exists(typed_class)) { @@ -1627,7 +1626,7 @@ namespace RC { // A type-specific implementation does not exist so lets call the default implementation for UObjects instead ObjectDumper::object_to_string(object, out_line); - out_line.append(L"\n"); + out_line.append(STR("\n")); } // If the UClass of the UObject has any properties then dump them @@ -1663,19 +1662,19 @@ namespace RC if (ObjectDumper::to_string_exists(typed_prop_class)) { ObjectDumper::get_to_string(typed_prop_class)(property, out_line); - out_line.append(L"\n"); + out_line.append(STR("\n")); if (ObjectDumper::to_string_complex_exists(typed_prop_class)) { ObjectDumper::get_to_string_complex(typed_prop_class)(property, out_line, [&]([[maybe_unused]] void* prop) { - out_line.append(L"\n"); + out_line.append(STR("\n")); }); } } else { ObjectDumper::property_to_string(property, out_line); - out_line.append(L"\n"); + out_line.append(STR("\n")); } } @@ -1731,7 +1730,7 @@ namespace RC // Make string & reserve massive amounts of space to hopefully not reach the end of the string and require more // dynamic allocations - std::wstring out_line; + StringType out_line; out_line.reserve(200000000); Output::send(STR("Dumping all objects & properties in GUObjectArray\n")); diff --git a/UE4SS/src/USMapGenerator/Generator.cpp b/UE4SS/src/USMapGenerator/Generator.cpp index 78d5517c8..051ce57e8 100644 --- a/UE4SS/src/USMapGenerator/Generator.cpp +++ b/UE4SS/src/USMapGenerator/Generator.cpp @@ -299,11 +299,11 @@ namespace RC::OutTheShade if (Object->GetClassPrivate() == UClass::StaticClass() || Object->GetClassPrivate() == UScriptStruct::StaticClass() || Object->GetClassPrivate() == UEnum::StaticClass()) { - std::wstring RawPathName = Object->GetPathName(); - std::wstring::size_type PathNameStart = + StringType RawPathName = Object->GetPathName(); + StringType::size_type PathNameStart = 0; // include first bit (Script/Game) to avoid ambiguity; to drop it, replace with RawPathName.find_first_of('/', 1) + 1; - std::wstring::size_type PathNameLength = RawPathName.find_last_of('.') - PathNameStart; - std::wstring FinalPathStr = RawPathName.substr(PathNameStart, PathNameLength); + StringType::size_type PathNameLength = RawPathName.find_last_of('.') - PathNameStart; + StringType FinalPathStr = RawPathName.substr(PathNameStart, PathNameLength); FName FinalPathName = FName(FinalPathStr); NameMap.insert_or_assign(FinalPathName, 0); diff --git a/UE4SS/src/main_ue4ss_rewritten.cpp b/UE4SS/src/main_ue4ss_rewritten.cpp index a6b836933..54345e628 100644 --- a/UE4SS/src/main_ue4ss_rewritten.cpp +++ b/UE4SS/src/main_ue4ss_rewritten.cpp @@ -29,7 +29,7 @@ auto thread_dll_start(UE4SSProgram* program) -> unsigned long // Logging will only happen to the debug console but it's something at least if (!Output::has_internal_error()) { - Output::send(STR("Fatal Error: {}\n"), to_wstring(e->get_message())); + Output::send(STR("Fatal Error: {}\n"), ensure_str(e->get_message())); } else { diff --git a/UVTD/src/UVTD.cpp b/UVTD/src/UVTD.cpp index b65488a5e..c782f1175 100644 --- a/UVTD/src/UVTD.cpp +++ b/UVTD/src/UVTD.cpp @@ -22,10 +22,12 @@ #include #include +#include + namespace RC::UVTD { bool processing_events{false}; - Input::Handler input_handler{L"ConsoleWindowClass", L"UnrealWindow"}; + Input::Handler input_handler{STR("ConsoleWindowClass"), STR("UnrealWindow")}; auto static event_loop_update() -> void { diff --git a/cppmods/KismetDebuggerMod/include/KismetDebugger.hpp b/cppmods/KismetDebuggerMod/include/KismetDebugger.hpp index c9592ccb4..763454926 100644 --- a/cppmods/KismetDebuggerMod/include/KismetDebugger.hpp +++ b/cppmods/KismetDebuggerMod/include/KismetDebugger.hpp @@ -33,14 +33,14 @@ namespace RC::GUI::KismetDebuggerMod auto has_breakpoint(UFunction* fn, size_t index) -> bool; auto add_breakpoint(UFunction* fn, size_t index) -> void; - auto add_breakpoint(const std::wstring& fn, size_t index) -> void; + auto add_breakpoint(const StringType& fn, size_t index) -> void; auto remove_breakpoint(UFunction* fn, size_t index) -> void; private: typedef std::unordered_set FunctionBreakpoints; std::unordered_map > m_breakpoints_by_function{}; - std::unordered_map > m_breakpoints_by_name{}; + std::unordered_map > m_breakpoints_by_name{}; }; class Debugger diff --git a/cppmods/KismetDebuggerMod/src/KismetDebugger.cpp b/cppmods/KismetDebuggerMod/src/KismetDebugger.cpp index cb7ee294c..d1081acd7 100644 --- a/cppmods/KismetDebuggerMod/src/KismetDebugger.cpp +++ b/cppmods/KismetDebuggerMod/src/KismetDebugger.cpp @@ -93,7 +93,7 @@ namespace RC::GUI::KismetDebuggerMod for (const auto& [fn, bps] : breakpoints) { - auto wfn = to_wstring(fn); + auto wfn = ensure_str(fn); for (const auto& bp : bps) { add_breakpoint(wfn, bp); @@ -186,7 +186,7 @@ namespace RC::GUI::KismetDebuggerMod } */ } - auto BreakpointStore::add_breakpoint(const std::wstring& fn, size_t index) -> void + auto BreakpointStore::add_breakpoint(const StringType& fn, size_t index) -> void { std::shared_ptr bps; auto [it_name, inserted_name] = m_breakpoints_by_name.emplace(fn, nullptr); @@ -215,7 +215,7 @@ namespace RC::GUI::KismetDebuggerMod Debugger::Debugger() : m_breakpoints(g_breakpoints) { - m_save_path = StringType{UE4SSProgram::get_program().get_working_directory()} + std::format(STR("\\Mods\\KismetDebugger\\config\\breakpoints.json")); + m_save_path = StringType{UE4SSProgram::get_program().get_working_directory()} + fmt::format(STR("\\Mods\\KismetDebugger\\config\\breakpoints.json")); } Debugger::~Debugger() { @@ -262,7 +262,7 @@ namespace RC::GUI::KismetDebuggerMod } catch (std::exception& e) { - Output::send(STR("[KismetDebugger]: Failed to load breakpoints: {}\n"), to_wstring(e.what())); + Output::send(STR("[KismetDebugger]: Failed to load breakpoints: {}\n"), ensure_str(e.what())); } // scan for GNatives if it hasn't been found yet @@ -362,12 +362,12 @@ namespace RC::GUI::KismetDebuggerMod { if (auto data_ptr = get_object_address(property, expr, context); data_ptr) { - auto popup_context_name = to_string(std::format(STR("{}-{}-{}"), static_cast(fn), index, static_cast(property))); + auto popup_context_name = to_string(fmt::format(STR("{}-{}-{}"), static_cast(fn), index, static_cast(property))); if (ImGui::BeginPopupContextItem(popup_context_name.c_str())) { if (ImGui::MenuItem("Copy address")) { - ImGui::SetClipboardText(std::format("{}", data_ptr).c_str()); + ImGui::SetClipboardText(fmt::format("{}", data_ptr).c_str()); } ImGui::EndPopup(); } diff --git a/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp b/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp index 5da40b8ee..7b17df3bd 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ #if RC_IS_ANSI == 1 #define RC_STD_MAKE_FORMAT_ARGS fmt::make_format_args #else -#define RC_STD_MAKE_FORMAT_ARGS fmt::make_wformat_args +#define RC_STD_MAKE_FORMAT_ARGS fmt::make_format_args> #endif namespace RC::Output @@ -123,11 +124,11 @@ namespace RC::Output if (device->has_optional_arg()) { - device->receive_with_optional_arg(fmt::vformat(content), RC_STD_MAKE_FORMAT_ARGS(static_cast(optional_arg))); + device->receive_with_optional_arg(content, static_cast(optional_arg)); } else { - device->receive(fmt::vformat(content)); + device->receive(content); } } } diff --git a/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp b/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp index f8b8b371e..c08d604dd 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp @@ -65,7 +65,7 @@ namespace RC::Output #if ENABLE_OUTPUT_DEVICE_DEBUG_MODE printf_s("TestDevice received: %S", fmt.c_str()); #else - printf_s("%S", fmt.data()); + printf_s("%S", FromCharTypePtr(fmt.data())); #endif } }; diff --git a/deps/first/File/src/FileType/WinFile.cpp b/deps/first/File/src/FileType/WinFile.cpp index fcc4a0793..e6316b769 100644 --- a/deps/first/File/src/FileType/WinFile.cpp +++ b/deps/first/File/src/FileType/WinFile.cpp @@ -383,14 +383,14 @@ namespace RC::File auto WinFile::write_string_to_file(StringViewType string_to_write) -> void { - int string_size = WideCharToMultiByte(CP_UTF8, 0, string_to_write.data(), static_cast(string_to_write.size()), NULL, 0, NULL, NULL); + int string_size = WideCharToMultiByte(CP_UTF8, 0, FromCharTypePtr(string_to_write.data()), static_cast(string_to_write.size()), NULL, 0, NULL, NULL); if (string_size == 0) { THROW_INTERNAL_FILE_ERROR(fmt::format("[WinFile::write_string_to_file] Tried writing string to file but string_size was 0. Error: {}", GetLastError())) } std::string string_converted_to_utf8(string_size, 0); - if (WideCharToMultiByte(CP_UTF8, 0, string_to_write.data(), static_cast(string_to_write.size()), &string_converted_to_utf8[0], string_size, NULL, NULL) == + if (WideCharToMultiByte(CP_UTF8, 0, FromCharTypePtr(string_to_write.data()), static_cast(string_to_write.size()), &string_converted_to_utf8[0], string_size, NULL, NULL) == 0) { THROW_INTERNAL_FILE_ERROR( diff --git a/deps/first/Helpers/include/Helpers/Format.hpp b/deps/first/Helpers/include/Helpers/Format.hpp index 329f91292..ce43dcd66 100644 --- a/deps/first/Helpers/include/Helpers/Format.hpp +++ b/deps/first/Helpers/include/Helpers/Format.hpp @@ -2,6 +2,8 @@ #include +#include + namespace RC { template @@ -40,7 +42,7 @@ namespace RC // Attempt to give a hint if the buffer is too small if (msg_len > out_string_length) { - fmt = L"An error occurred but the message was too long for the buffer."; + fmt = STR("An error occurred but the message was too long for the buffer."); msg_len = wcslen(fmt); } diff --git a/deps/first/Helpers/include/Helpers/String.hpp b/deps/first/Helpers/include/Helpers/String.hpp index e8f964060..7cf206978 100644 --- a/deps/first/Helpers/include/Helpers/String.hpp +++ b/deps/first/Helpers/include/Helpers/String.hpp @@ -7,8 +7,9 @@ #include #include #include +#include -#include +#include namespace RC { @@ -27,14 +28,15 @@ namespace RC FromEnd }; - auto inline explode_by_occurrence(const std::wstring& in_str_wide, const wchar_t delimiter, ExplodeType start_or_end) -> std::wstring + template + auto inline explode_by_occurrence(const std::basic_string& in_str_wide, const CharT delimiter, ExplodeType start_or_end) -> std::basic_string { size_t occurrence = (start_or_end == ExplodeType::FromStart ? in_str_wide.find_first_of(delimiter) : in_str_wide.find_last_of(delimiter)); - std::wstring return_value; - if (occurrence != std::wstring::npos) + std::basic_string return_value; + if (occurrence != std::basic_string::npos) { - return_value = start_or_end == ExplodeType::FromEnd ? in_str_wide.substr(occurrence + 1, std::wstring::npos) : in_str_wide.substr(0, occurrence); + return_value = start_or_end == ExplodeType::FromEnd ? in_str_wide.substr(occurrence + 1, std::basic_string::npos) : in_str_wide.substr(0, occurrence); } else { @@ -44,24 +46,8 @@ namespace RC return return_value; } - auto inline explode_by_occurrence(const std::string& in_str, const char delimiter, ExplodeType start_or_end) -> std::string - { - size_t occurrence = (start_or_end == ExplodeType::FromStart ? in_str.find_first_of(delimiter) : in_str.find_last_of(delimiter)); - - std::string return_value; - if (occurrence != std::string::npos) - { - return_value = start_or_end == ExplodeType::FromEnd ? in_str.substr(occurrence + 1, std::string::npos) : in_str.substr(0, occurrence); - } - else - { - return_value = in_str; - } - - return return_value; - } - - auto inline explode_by_occurrence(const std::string& in_str, const char delimiter, const int32_t occurrence) -> std::string + template + auto inline explode_by_occurrence(const std::basic_string& in_str, const char delimiter, const int32_t occurrence) -> std::basic_string { size_t found_occurrence{}; for (int64_t i = 0; i < std::count(in_str.begin(), in_str.end(), delimiter); i++) @@ -77,45 +63,19 @@ namespace RC return {}; } - auto inline explode_by_occurrence(const std::string& in_str, const char delimiter) -> std::vector + template + auto inline explode_by_occurrence(const std::basic_string& in_str, const char delimiter) -> std::vector> { - std::vector result; + std::vector> result; size_t counter{}; size_t start_offset{}; - for (const char* current_char = in_str.c_str(); *current_char; ++current_char) + for (const CharT* current_char = in_str.c_str(); *current_char; ++current_char) { if (*current_char == delimiter || counter == in_str.length() - 1) { - std::string sub_str = in_str.substr(start_offset, counter - start_offset + (counter == in_str.length() - 1 ? 1 : 0)); - if (start_offset > 0) - { - sub_str.erase(0, 1); - } - result.emplace_back(sub_str); - - start_offset = counter; - } - - ++counter; - } - - return result; - } - - auto inline explode_by_occurrence(const std::wstring& in_str_wide, const wchar_t delimiter) -> std::vector - { - std::vector result; - - size_t counter{}; - size_t start_offset{}; - - for (const wchar_t* current_char = in_str_wide.c_str(); *current_char; ++current_char) - { - if (*current_char == delimiter || counter == in_str_wide.length() - 1) - { - std::wstring sub_str = in_str_wide.substr(start_offset, counter - start_offset + (counter == in_str_wide.length() - 1 ? 1 : 0)); + std::basic_string sub_str = in_str.substr(start_offset, counter - start_offset + (counter == in_str.length() - 1 ? 1 : 0)); if (start_offset > 0) { sub_str.erase(0, 1); @@ -131,7 +91,8 @@ namespace RC return result; } - auto inline explode_by_occurrence(const std::wstring& in_str, const wchar_t delimiter, const int32_t occurrence) -> std::wstring + template + auto inline explode_by_occurrence(const std::basic_string& in_str, const CharT delimiter, const int32_t occurrence) -> std::basic_string { size_t found_occurrence{}; for (int64_t i = 0; i < std::count(in_str.begin(), in_str.end(), delimiter); i++) @@ -156,45 +117,54 @@ namespace RC #pragma warning(default : 4996) } - auto inline to_const_wstring(std::string_view input) -> const std::wstring& + auto inline to_wstring(std::string_view input) -> std::wstring { - static std::unordered_map wstringpool; - static std::shared_mutex wstringpool_lock; - - // Allow multiple readers that are stalled when any thread is writing. - { - std::shared_lock read_guard(wstringpool_lock); - if (wstringpool.contains(input)) return wstringpool[input]; - } - - auto temp_input = std::string{input}; - auto new_str = to_wstring(temp_input); +#ifdef PLATFORM_WINDOWS +#pragma warning(disable : 4996) + static std::wstring_convert> converter{}; + return converter.from_bytes(input.data(), input.data() + input.length()); +#pragma warning(default : 4996) +#else +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + static std::wstring_convert> converter{}; + return converter.from_bytes(input.data(), input.data() + input.length()); +#endif +#if __clang__ +#pragma clang diagnostic pop +#endif + } - // Stall the readers to insert a new string. - { - std::lock_guard write_guard(wstringpool_lock); - const auto& [emplaced_iter, unused] = wstringpool.emplace(input, std::move(new_str)); - return emplaced_iter->second; - } + auto inline to_wstring(std::wstring_view input) -> std::wstring + { + return std::wstring{input}; } - auto inline to_wstring(std::string_view input) -> std::wstring + auto inline to_wstring(std::wstring& input) -> std::wstring { - auto temp_input = std::string{input}; - return to_wstring(temp_input); + return std::wstring{input}; } auto inline to_wstring(std::u16string& input) -> std::wstring { +#ifdef PLATFORM_WINDOWS return {input.begin(), input.end()}; +#else + throw std::runtime_error{"There is no reason to use this function on non-Windows platforms"}; +#endif } auto inline to_wstring(std::u16string_view input) -> std::wstring { - auto temp_input = std::u16string{input}; - return to_wstring(temp_input); +#ifdef PLATFORM_WINDOWS + return {input.begin(), input.end()}; +#else + throw std::runtime_error{"There is no reason to use this function on non-Windows platforms"}; +#endif } - + auto inline to_string(std::wstring& input) -> std::string { #pragma warning(disable : 4996) @@ -209,6 +179,21 @@ namespace RC return to_string(temp_input); } + auto inline to_string(std::u16string_view input) -> std::string + { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif +#pragma warning(disable : 4996) + static std::wstring_convert, char16_t> converter{}; + return converter.to_bytes(input.data(), input.data() + input.length()); +#pragma warning(default : 4996) +#if __clang__ +#pragma clang diagnostic pop +#endif + } + auto inline to_u16string(std::wstring& input) -> std::u16string { return {input.begin(), input.end()}; @@ -231,6 +216,134 @@ namespace RC return to_u16string(temp_input); } + // Auto String Conversion + + // All possible char types in this project + template + struct _can_be_string_view_t : std::false_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + + template + struct can_be_string_view_t : _can_be_string_view_t> + { + }; + + template + struct is_string_like_t : std::false_type + { + }; + + template + struct is_string_like_t> : std::true_type + { + // T is a string or string view of CharT + }; + + template + struct is_string_like_t> : std::true_type + { + // T is a string or string view of CharT + }; + + template + struct is_charT_string_type : std::disjunction>, std::is_same>> + { + // T is a string or string view of CharT + }; + + template + struct not_charT_string_like_t : std::conjunction>, std::negation, CharT>>> + { + // 1. T is a string or string view + // 2. T is not a string or string view of CharT + }; + + template + auto stringviewify(T&& tp) + { + // Convert a char pointer to a string view + return std::basic_string_view>>>{tp}; + } + + template + auto inline to_charT_string(T&& arg) -> std::basic_string { + // Dispatch to the correct conversion function based on the CharT type + if constexpr (std::is_same_v) { + return to_wstring(std::forward(arg)); + } else if constexpr (std::is_same_v) { + return to_u16string(std::forward(arg)); + } else if constexpr (std::is_same_v) { + return to_string(std::forward(arg)); + } + } + + template + auto inline to_charT_string_path(T&& arg) -> std::basic_string { + // Dispatch to the correct conversion function based on the CharT type + if constexpr (std::is_same_v) { + return arg.wstring(); + } else if constexpr (std::is_same_v) { + return arg.u16string(); + } else if constexpr (std::is_same_v) { + return arg.string(); + } + } + + // Convert any string-like to a string of generic CharT + // Or pass through if it's already a string(view) of CharType or if we can't convert it + template + auto inline to_charT(T&& arg) { + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) { + // std::filesystem::path has its own conversion functions + return to_charT_string_path(std::forward(arg)); + } else if constexpr (can_be_string_view_t::value) { + // If T is a char pointer, it can be treated as a string view + return to_charT(stringviewify(std::forward(arg))); + } else if constexpr (not_charT_string_like_t::value) { + // If T is a string or string view but not using CharT, convert it + return to_charT_string(std::forward(arg)); + } else { + // If T is already a string or string view using CharT, pass through + // Or if we can't convert it, pass through + return std::forward(arg); + } + } + + // Ensure that a string is compatible with UE4SS, converting it if neccessary + template + auto inline ensure_str(T&& arg) { + return to_charT(std::forward(arg)); + } + + // You can add more to_* function if needed + + // Auto Type Conversion Done + auto inline to_generic_string(const auto& input) -> StringType { if constexpr (std::is_same_v>>, StringViewType>) @@ -247,45 +360,58 @@ namespace RC #if RC_IS_ANSI == 1 return to_string(input); #else - return to_wstring(input); + return ensure_str(input); #endif } } - - namespace String + auto inline ensure_str_const(std::string_view input) -> const StringType& { - auto inline iequal(std::wstring_view a, std::wstring_view b) + static std::unordered_map uestringpool; + static std::shared_mutex uestringpool_lock; + + // Allow multiple readers that are stalled when any thread is writing. { - return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), [](const wchar_t a_char, const wchar_t b_char) { - return std::towlower(a_char) == std::towlower(b_char); - }); + std::shared_lock read_guard(uestringpool_lock); + if (uestringpool.contains(input)) return uestringpool[input]; } - auto inline iequal(std::wstring& a, const wchar_t* b) + auto temp_input = std::string{input}; + auto new_str = ensure_str(temp_input); + + // Stall the readers to insert a new string. { - return iequal(a, std::wstring_view{b}); + std::lock_guard write_guard(uestringpool_lock); + const auto& [emplaced_iter, unused] = uestringpool.emplace(input, std::move(new_str)); + return emplaced_iter->second; } - - auto inline iequal(const wchar_t* a, std::wstring& b) + } + + namespace String + { + template + auto inline iequal(std::basic_string_view a, std::basic_string_view b) { - return iequal(std::wstring_view{a}, b); + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), [](const CharT a_char, const CharT b_char) { + return std::towlower((wchar_t) a_char) == std::towlower((wchar_t) b_char); + }); } - auto inline iequal(std::string_view a, std::string_view b) + template + auto inline iequal(std::basic_string& a, const CharT* b) { - return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), [](const char a_char, const char b_char) { - return (std::tolower(a_char) == std::tolower(b_char)); - }); + return iequal(std::basic_string_view{a}, std::basic_string_view{b}); } - auto inline iequal(std::string& a, const char* b) + template + auto inline iequal(const CharT* a, std::basic_string& b) { - return iequal(a, std::string_view{b}); + return iequal(std::basic_string_view{a}, std::basic_string_view{b}); } - auto inline str_cmp_insensitive(const char* a, std::string& b) + template + auto inline str_cmp_insensitive(const CharT* a, std::basic_string& b) { - return iequal(std::string_view{a}, b); + return iequal(std::basic_string_view{a}, std::basic_string_view{b}); } } // namespace String } // namespace RC diff --git a/deps/first/Helpers/xmake.lua b/deps/first/Helpers/xmake.lua index 626526998..4117e478f 100644 --- a/deps/first/Helpers/xmake.lua +++ b/deps/first/Helpers/xmake.lua @@ -6,6 +6,8 @@ target(projectName) set_exceptions("cxx") add_rules("ue4ss.dependency") + add_deps("String") + add_includedirs("include", { public = true }) add_headerfiles("include/**.hpp") diff --git a/deps/first/IniParser/include/IniParser/Experimental.hpp b/deps/first/IniParser/include/IniParser/Experimental.hpp index 38c8039eb..c84f2606b 100644 --- a/deps/first/IniParser/include/IniParser/Experimental.hpp +++ b/deps/first/IniParser/include/IniParser/Experimental.hpp @@ -3,6 +3,9 @@ #include #include #include +#include + +#include namespace RC::Parser::Experimental { @@ -24,47 +27,47 @@ namespace RC::Parser::Experimental class RuleOne : public Parser::TokenRule { public: - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> StringType override { - return L"RuleOne"; + return STR("RuleOne"); } }; class TokenMustEndWithOppositeToken : public Parser::TokenRule { public: - TokenMustEndWithOppositeToken() : TokenRule(L"TokenMustEndWithOppositeToken") + TokenMustEndWithOppositeToken() : TokenRule(STR("TokenMustEndWithOppositeToken")) { } - auto exec(const Parser::Token& token, const wchar_t* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override + auto exec(const Parser::Token& token, const CharType* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override { printf_s("TokenMustEndWithOppositeToken::exec [%S]\n", token.to_string().c_str()); return 0; } - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> StringType override { - return L"TokenMustEndWithOppositeToken"; + return STR("TokenMustEndWithOppositeToken"); } }; class TokenMustHaveCharsBeforeEnd : public Parser::TokenRule { public: - TokenMustHaveCharsBeforeEnd() : TokenRule(L"TokenMustHaveCharsBeforeEnd") + TokenMustHaveCharsBeforeEnd() : TokenRule(STR("TokenMustHaveCharsBeforeEnd")) { } - auto exec(const Parser::Token& token, const wchar_t* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override + auto exec(const Parser::Token& token, const CharType* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override { printf_s("TokenMustHaveCharsBeforeEnd::exec [%S]\n", token.to_string().c_str()); return 0; } - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> StringType override { - return L"TokenMustHaveCharsBeforeEnd"; + return STR("TokenMustHaveCharsBeforeEnd"); } }; @@ -76,35 +79,35 @@ namespace RC::Parser::Experimental // Always use "ref->value" instead of "value" // That way it returns properly if this value is a refernece to another variable // The "ref->value" member is set to self if it doesn't refer to another variable - std::wstring value{}; + StringType value{}; const Value* ref{}; }; struct Section { - std::unordered_map key_value_pairs{}; + std::unordered_map key_value_pairs{}; }; private: - using SectionContainer = std::unordered_map; + using SectionContainer = std::unordered_map; SectionContainer& m_output; Section* m_current_section{}; Value* m_variable_to_assign_to{}; - std::wstring m_temporary{}; + StringType m_temporary{}; public: - ExperimentalTokenParser(const Parser::Tokenizer& tokenizer, std::wstring input, std::unordered_map& output) + ExperimentalTokenParser(const Parser::Tokenizer& tokenizer, StringType input, std::unordered_map& output) : TokenParser(tokenizer, input), m_output(output) { } public: - auto static find_variable_by_name(Section* section, const std::wstring& name) -> std::optional>; - auto static find_variable_by_name(SectionContainer& sections, const std::wstring& name) -> std::optional>; + auto static find_variable_by_name(Section* section, const StringType& name) -> std::optional>; + auto static find_variable_by_name(SectionContainer& sections, const StringType& name) -> std::optional>; private: - auto find_variable_by_name(const std::wstring& name) -> std::optional>; + auto find_variable_by_name(const StringType& name) -> std::optional>; auto try_set_section_value(Value& pair_value, const Parser::Token& token, bool is_space_valid = true) -> void; auto handle_operator_equals(const Parser::Token& token) -> void; auto handle_operator_plus(const Parser::Token& token) -> void; @@ -120,16 +123,16 @@ namespace RC::Parser::Experimental class ExperimentalParser { private: - std::unordered_map m_sections; + std::unordered_map m_sections; public: - ExperimentalParser(const std::wstring& input); + ExperimentalParser(const StringType& input); private: auto create_available_tokens_for_tokenizer() -> Parser::TokenContainer; public: - auto get_string(const std::wstring& section, const std::wstring& key, const std::wstring& default_value) -> std::wstring; + auto get_string(const StringType& section, const StringType& key, const StringType& default_value) -> StringType; }; auto test() -> void; diff --git a/deps/first/IniParser/include/IniParser/TokenParser.hpp b/deps/first/IniParser/include/IniParser/TokenParser.hpp index a7192852a..5b7fa315d 100644 --- a/deps/first/IniParser/include/IniParser/TokenParser.hpp +++ b/deps/first/IniParser/include/IniParser/TokenParser.hpp @@ -8,6 +8,8 @@ #include "Section.hpp" #include "Tokens.hpp" +#include + namespace RC::Ini { class Value; diff --git a/deps/first/IniParser/src/Experimental.cpp b/deps/first/IniParser/src/Experimental.cpp index 9e143cb02..a63fec33e 100644 --- a/deps/first/IniParser/src/Experimental.cpp +++ b/deps/first/IniParser/src/Experimental.cpp @@ -2,7 +2,7 @@ namespace RC::Parser::Experimental { - auto ExperimentalTokenParser::find_variable_by_name(Section* section, const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(Section* section, const StringType& name) -> std::optional> { auto const& var = section->key_value_pairs.find(name); if (var != section->key_value_pairs.end()) @@ -15,7 +15,7 @@ namespace RC::Parser::Experimental } } - auto ExperimentalTokenParser::find_variable_by_name(SectionContainer& sections, const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(SectionContainer& sections, const StringType& name) -> std::optional> { std::optional> value_found = [&]() -> std::optional> { for (auto& [_, section] : sections) @@ -33,9 +33,9 @@ namespace RC::Parser::Experimental return value_found; } - auto ExperimentalTokenParser::find_variable_by_name(const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(const StringType& name) -> std::optional> { - size_t occurrence_of_dot = name.find_first_of(L'.'); + size_t occurrence_of_dot = name.find_first_of(STR('.')); if (occurrence_of_dot == name.npos || occurrence_of_dot + 1 > name.size()) { return find_variable_by_name(m_current_section, name); @@ -49,7 +49,7 @@ namespace RC::Parser::Experimental } else { - const std::wstring requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); + const StringType requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); return find_variable_by_name(&requested_section->second, requested_variable_name); } } @@ -60,12 +60,12 @@ namespace RC::Parser::Experimental const auto token_type = token.get_type(); if (token_type == TokenType::EndOfFile || token_type == TokenType::NewLine) { - pair_value.value = L""; + pair_value.value = STR(""); pair_value.ref = &pair_value; } else if (token_type == TokenType::Characters) { - std::wstring value_data{}; + StringType value_data{}; consume_continually([&](const Parser::Token& token) { const auto token_type = token.get_type(); if (token_type == TokenType::EndOfFile || token_type == TokenType::NewLine) @@ -85,7 +85,7 @@ namespace RC::Parser::Experimental else if (token_type == TokenType::Space) { // Append space - value_data.append(L" "); + value_data.append(STR(" ")); // Consume another token return false; @@ -161,7 +161,7 @@ namespace RC::Parser::Experimental } else if (previous_token.get_type() == TokenType::Characters) { - std::wstring key_name = get_data(previous_token); + StringType key_name = get_data(previous_token); const auto& key_value_pair_iter = m_current_section->key_value_pairs.find(key_name); if (key_value_pair_iter == m_current_section->key_value_pairs.end()) { @@ -188,7 +188,7 @@ namespace RC::Parser::Experimental } else if (characters_token.get_type() == TokenType::Characters) { - const std::wstring key_name = get_data(characters_token); + const StringType key_name = get_data(characters_token); const auto& maybe_variable = find_variable_by_name(key_name); if (maybe_variable.has_value()) { @@ -250,7 +250,7 @@ namespace RC::Parser::Experimental // May be a variable or a temporary (Characters token) bool lhs_is_variable{}; bool lhs_is_temporary{}; - std::wstring lhs = [&]() { + StringType lhs = [&]() { if (!m_temporary.empty()) { lhs_is_temporary = true; @@ -265,7 +265,7 @@ namespace RC::Parser::Experimental } else { - const std::wstring lhs_data = get_data(lhs_token); + const StringType lhs_data = get_data(lhs_token); auto maybe_variable = find_variable_by_name(lhs_data); if (maybe_variable.has_value()) { @@ -306,8 +306,8 @@ namespace RC::Parser::Experimental // } // Find rhs - std::wstring rhs = [&]() { - std::wstring rhs_temporary{}; + StringType rhs = [&]() { + StringType rhs_temporary{}; const auto& next_token = peek(); if (next_token.get_type() == TokenType::EndOfFile) @@ -332,7 +332,7 @@ namespace RC::Parser::Experimental } else if (next_token.get_type() == TokenType::Space) { - rhs_temporary += L" "; + rhs_temporary += STR(" "); consume(); // Consume the first Space consume_until(TokenType::Characters, [&](const Parser::Token& token) { @@ -346,7 +346,7 @@ namespace RC::Parser::Experimental } else { - rhs_temporary += L" "; + rhs_temporary += STR(" "); return false; } } @@ -476,7 +476,7 @@ namespace RC::Parser::Experimental } }(); - std::wstring section_name = get_data(section_name_token); + StringType section_name = get_data(section_name_token); if (auto section = m_output.find(section_name); section != m_output.end()) { m_current_section = §ion->second; @@ -515,7 +515,7 @@ namespace RC::Parser::Experimental } } - ExperimentalParser::ExperimentalParser(const std::wstring& input) + ExperimentalParser::ExperimentalParser(const StringType& input) { // Tokenize -> START Parser::Tokenizer tokenizer; @@ -533,28 +533,28 @@ namespace RC::Parser::Experimental { Parser::TokenContainer tc; - tc.add(Parser::Token::create(TokenType::CarriageReturn, L"CarriageReturn", L"\r")); - tc.add(Parser::Token::create(TokenType::NewLine, L"NewLine", L"\n")); - tc.add(Parser::Token::create(TokenType::Space, L"Space", L" ")); + tc.add(Parser::Token::create(TokenType::CarriageReturn, STR("CarriageReturn"), STR("\r"))); + tc.add(Parser::Token::create(TokenType::NewLine, STR("NewLine"), STR("\n"))); + tc.add(Parser::Token::create(TokenType::Space, STR("Space"), STR(" "))); tc.add(Parser::Token::create(TokenType::Characters, - L"Characters", + STR("Characters"), L"", Parser::Token::HasData::Yes)); // Empty identifier will match everything that no other token identifier matches - tc.add(Parser::Token::create(TokenType::Equals, L"Equals", L"=")); - // tc.add(Parser::Token::create(IniFileToken::Plus, L"Plus", L"+")); + tc.add(Parser::Token::create(TokenType::Equals, STR("Equals"), STR("="))); + // tc.add(Parser::Token::create(IniFileToken::Plus, STR("Plus"), STR("+"))); - auto close_square_bracket_token = tc.add(Parser::Token::create(TokenType::ClosingSquareBracket, L"CloseSquareBracket", L"]")); + auto close_square_bracket_token = tc.add(Parser::Token::create(TokenType::ClosingSquareBracket, STR("CloseSquareBracket"), STR("]"))); auto token = - Parser::Token::create(TokenType::OpeningSquareBracket, L"OpenSquareBracket", L"["); + Parser::Token::create(TokenType::OpeningSquareBracket, STR("OpenSquareBracket"), STR("[")); tc.add(std::move(token)); - tc.add(Parser::Token::create(TokenType::SemiColon, L"SemiColon", L";")); + tc.add(Parser::Token::create(TokenType::SemiColon, STR("SemiColon"), STR(";"))); return tc; } - auto ExperimentalParser::get_string(const std::wstring& section, const std::wstring& key, const std::wstring& default_value) -> std::wstring + auto ExperimentalParser::get_string(const StringType& section, const StringType& key, const StringType& default_value) -> StringType { auto section_iter = m_sections.find(section); if (section_iter == m_sections.end()) @@ -590,7 +590,7 @@ var6 = hello + + world var7 = 1 + 2 + 3 + 4 */ - std::wstring config_str = LR"( + StringType config_str = LR"( [ SectionOne] ; This is a comment and as such should be ignored by the parser var1 = 2 @@ -624,30 +624,30 @@ var5 = a string with spaces printf_s("Creating experimental parser\n"); ExperimentalParser parser{config_str}; - constexpr wchar_t default_value[] = L""; - printf_s("SectionOne.var1 = %S\n", parser.get_string(L"SectionOne", L"var1", default_value).c_str()); - printf_s("SectionOne.var2 = %S\n", parser.get_string(L"SectionOne", L"var2", default_value).c_str()); - printf_s("SectionOne.var3 = %S\n", parser.get_string(L"SectionOne", L"var3", default_value).c_str()); - printf_s("SectionOne.var4 = %S\n", parser.get_string(L"SectionOne", L"var4", default_value).c_str()); - printf_s("SectionOne.var5 = %S\n", parser.get_string(L"SectionOne", L"var5", default_value).c_str()); - printf_s("SectionOne.var6 = %S\n", parser.get_string(L"SectionOne", L"var6", default_value).c_str()); - printf_s("SectionOne.var7 = %S\n", parser.get_string(L"SectionOne", L"var7", default_value).c_str()); + constexpr auto default_value[] = STR(""); + printf_s("SectionOne.var1 = %S\n", parser.get_string(STR("SectionOne"), STR("var1"), default_value).c_str()); + printf_s("SectionOne.var2 = %S\n", parser.get_string(STR("SectionOne"), STR("var2"), default_value).c_str()); + printf_s("SectionOne.var3 = %S\n", parser.get_string(STR("SectionOne"), STR("var3"), default_value).c_str()); + printf_s("SectionOne.var4 = %S\n", parser.get_string(STR("SectionOne"), STR("var4"), default_value).c_str()); + printf_s("SectionOne.var5 = %S\n", parser.get_string(STR("SectionOne"), STR("var5"), default_value).c_str()); + printf_s("SectionOne.var6 = %S\n", parser.get_string(STR("SectionOne"), STR("var6"), default_value).c_str()); + printf_s("SectionOne.var7 = %S\n", parser.get_string(STR("SectionOne"), STR("var7"), default_value).c_str()); printf_s("\n"); - printf_s("SectionTwo.var1 = %S\n", parser.get_string(L"SectionTwo", L"var1", default_value).c_str()); - printf_s("SectionTwo.var2 = %S\n", parser.get_string(L"SectionTwo", L"var2", default_value).c_str()); - printf_s("SectionTwo.var3 = %S\n", parser.get_string(L"SectionTwo", L"var3", default_value).c_str()); - printf_s("SectionTwo.var4 = %S\n", parser.get_string(L"SectionTwo", L"var4", default_value).c_str()); - printf_s("SectionTwo.var5 = %S\n", parser.get_string(L"SectionTwo", L"var5", default_value).c_str()); - printf_s("SectionTwo.var6 = %S\n", parser.get_string(L"SectionTwo", L"var6", default_value).c_str()); - printf_s("SectionTwo.var7 = %S\n", parser.get_string(L"SectionTwo", L"var7", default_value).c_str()); - printf_s("SectionTwo.var8 = %S\n", parser.get_string(L"SectionTwo", L"var8", default_value).c_str()); - printf_s("SectionTwo.var9 = %S\n", parser.get_string(L"SectionTwo", L"var9", default_value).c_str()); - printf_s("SectionTwo.var10 = %S\n", parser.get_string(L"SectionTwo", L"var10", default_value).c_str()); + printf_s("SectionTwo.var1 = %S\n", parser.get_string(STR("SectionTwo"), STR("var1"), default_value).c_str()); + printf_s("SectionTwo.var2 = %S\n", parser.get_string(STR("SectionTwo"), STR("var2"), default_value).c_str()); + printf_s("SectionTwo.var3 = %S\n", parser.get_string(STR("SectionTwo"), STR("var3"), default_value).c_str()); + printf_s("SectionTwo.var4 = %S\n", parser.get_string(STR("SectionTwo"), STR("var4"), default_value).c_str()); + printf_s("SectionTwo.var5 = %S\n", parser.get_string(STR("SectionTwo"), STR("var5"), default_value).c_str()); + printf_s("SectionTwo.var6 = %S\n", parser.get_string(STR("SectionTwo"), STR("var6"), default_value).c_str()); + printf_s("SectionTwo.var7 = %S\n", parser.get_string(STR("SectionTwo"), STR("var7"), default_value).c_str()); + printf_s("SectionTwo.var8 = %S\n", parser.get_string(STR("SectionTwo"), STR("var8"), default_value).c_str()); + printf_s("SectionTwo.var9 = %S\n", parser.get_string(STR("SectionTwo"), STR("var9"), default_value).c_str()); + printf_s("SectionTwo.var10 = %S\n", parser.get_string(STR("SectionTwo"), STR("var10"), default_value).c_str()); printf_s("\n"); - printf_s("AnotherSection.var1 = %S\n", parser.get_string(L"AnotherSection", L"var1", default_value).c_str()); - printf_s("AnotherSection.var2 = %S\n", parser.get_string(L"AnotherSection", L"var2", default_value).c_str()); - printf_s("AnotherSection.var3 = %S\n", parser.get_string(L"AnotherSection", L"var3", default_value).c_str()); - printf_s("AnotherSection.var4 = %S\n", parser.get_string(L"AnotherSection", L"var4", default_value).c_str()); - printf_s("AnotherSection.var5 = %S\n", parser.get_string(L"AnotherSection", L"var5", default_value).c_str()); + printf_s("AnotherSection.var1 = %S\n", parser.get_string(STR("AnotherSection"), STR("var1"), default_value).c_str()); + printf_s("AnotherSection.var2 = %S\n", parser.get_string(STR("AnotherSection"), STR("var2"), default_value).c_str()); + printf_s("AnotherSection.var3 = %S\n", parser.get_string(STR("AnotherSection"), STR("var3"), default_value).c_str()); + printf_s("AnotherSection.var4 = %S\n", parser.get_string(STR("AnotherSection"), STR("var4"), default_value).c_str()); + printf_s("AnotherSection.var5 = %S\n", parser.get_string(STR("AnotherSection"), STR("var5"), default_value).c_str()); } } // namespace RC::Parser::Experimental diff --git a/deps/first/IniParser/src/JSON.cpp b/deps/first/IniParser/src/JSON.cpp index b7951e5f3..2de8a97e1 100644 --- a/deps/first/IniParser/src/JSON.cpp +++ b/deps/first/IniParser/src/JSON.cpp @@ -4,13 +4,10 @@ #include #include +#include + namespace RC::Parser { - static auto to_string(std::wstring in) -> std::string - { - return std::string{in.begin(), in.end()}; - } - static auto has_only_spaces(const File::StringType& data) -> bool { if (std::all_of(data.begin(), data.end(), [](File::CharType c) { diff --git a/deps/first/IniParser/src/TokenParser.cpp b/deps/first/IniParser/src/TokenParser.cpp index d15bd72a7..01021e9d9 100644 --- a/deps/first/IniParser/src/TokenParser.cpp +++ b/deps/first/IniParser/src/TokenParser.cpp @@ -32,10 +32,10 @@ namespace RC::Ini auto static is_int(File::StringViewType data) -> Int { bool has_0x_prefix = [&]() { - return (data.size() > 2 && data[0] == L'0' && (data[1] == L'x' || data[1] == L'X')); + return (data.size() > 2 && data[0] == STR('0') && (data[1] == STR('x') || data[1] == STR('X'))); }(); - if (!has_0x_prefix && data[0] != L'-' && std::iswdigit(data[0]) == 0) + if (!has_0x_prefix && data[0] != STR('-') && std::iswdigit(data[0]) == 0) { return Int{0, 10, false}; } @@ -47,14 +47,8 @@ namespace RC::Ini string = File::StringViewType{string.begin() + 1, string.end()}; } bool is_int = std::ranges::all_of(string.begin(), string.end(), [&](const File::CharType c) { - if constexpr (std::is_same_v) - { - return has_0x_prefix ? std::iswxdigit(c) : std::iswdigit(c) != 0; - } - else - { - return has_0x_prefix ? std::isxdigit(c) : std::isdigit(c) != 0; - } + // force the char type to wchar_t as it is always larger or equal to char type + return has_0x_prefix ? std::iswxdigit((wchar_t) c) : std::iswdigit((wchar_t) c) != 0; }); return Int{.value = 0, .base = has_0x_prefix ? 16 : 10, .is_int = is_int}; @@ -64,7 +58,7 @@ namespace RC::Ini auto static is_float(File::StringViewType data) -> Float { bool has_decimal_or_negative_prefix = [&]() { - return data.size() > 1 && data[0] == L'.' || data[0] == L'-'; + return data.size() > 1 && data[0] == STR('.') || data[0] == STR('-'); }(); if (!has_decimal_or_negative_prefix && std::iswdigit(data[0]) == 0) @@ -79,14 +73,7 @@ namespace RC::Ini string = File::StringViewType{string.begin() + 1, string.end()}; } bool is_float = std::ranges::all_of(string.begin(), string.end(), [&](const File::CharType c) { - if constexpr (std::is_same_v) - { - return has_decimal_or_negative_prefix ? std::iswxdigit(c) : std::iswdigit(c) != 0 || c == STR('.'); - } - else - { - return has_decimal_or_negative_prefix ? std::isxdigit(c) : std::isdigit(c) != 0 || c == STR('.'); - } + return has_decimal_or_negative_prefix ? std::iswxdigit((wchar_t) c) : std::iswdigit((wchar_t) c) != 0 || c == STR('.'); }); return Float{.value = 0, .is_float = is_float}; @@ -99,8 +86,8 @@ namespace RC::Ini // TODO: This to_lower implementation is not string-type agnostic // A code change would be required if 'File::StringType' is defined as a char instead of a wchar_t // Solution: Make two overloads in the string helper library, one for 'std::string' and one for 'std::wstring' - std::transform(all_lower_string_data.begin(), all_lower_string_data.end(), all_lower_string_data.begin(), [](wchar_t c) { - return std::towlower(c); + std::transform(all_lower_string_data.begin(), all_lower_string_data.end(), all_lower_string_data.begin(), [](CharType c) { + return (CharType) std::towlower((wchar_t) c); }); if (all_lower_string_data == STR("true") || all_lower_string_data == STR("1")) { @@ -131,7 +118,7 @@ namespace RC::Ini auto TokenParser::find_variable_by_name(const StringType& name) -> std::optional> { - size_t occurrence_of_dot = name.find_first_of(L'.'); + size_t occurrence_of_dot = name.find_first_of(STR('.')); if (occurrence_of_dot == name.npos || occurrence_of_dot + 1 > name.size()) { return find_variable_by_name(m_current_section, name); diff --git a/deps/first/IniParser/src/Value.cpp b/deps/first/IniParser/src/Value.cpp index 05e79ee57..1bc08b787 100644 --- a/deps/first/IniParser/src/Value.cpp +++ b/deps/first/IniParser/src/Value.cpp @@ -1,4 +1,5 @@ #include +#include namespace RC::Ini { @@ -54,7 +55,7 @@ namespace RC::Ini auto Value::add_int64_value(const StringType& data, int base) -> void { - m_int64_value = std::stoi(data, nullptr, base); + m_int64_value = std::stoi(to_string(data), nullptr, base); if (!m_ref) { @@ -66,7 +67,7 @@ namespace RC::Ini auto Value::add_float_value(const StringType& data) -> void { - m_float_value = std::stof(data, nullptr); + m_float_value = std::stof(to_string(data), nullptr); if (!m_ref) { diff --git a/deps/first/JSON/include/JSON/KeyValuePair.hpp b/deps/first/JSON/include/JSON/KeyValuePair.hpp index 208901e75..9c4d76a19 100644 --- a/deps/first/JSON/include/JSON/KeyValuePair.hpp +++ b/deps/first/JSON/include/JSON/KeyValuePair.hpp @@ -191,7 +191,7 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; auto get(StringViewType key) const -> ValueType& { auto value = find_value_by_key(key); - if (!value) { throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; } + if (!value) { throw std::runtime_error{to_string(fmt::format(STR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } @@ -199,7 +199,7 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; auto get(StringViewType key) -> ValueType& { auto value = find_value_by_key(key); - if (!value) { throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; } + if (!value) { throw std::runtime_error{to_string(fmt::format(STR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } }; diff --git a/deps/first/JSON/include/JSON/Object.hpp b/deps/first/JSON/include/JSON/Object.hpp index 25cb344ad..2321d7d59 100644 --- a/deps/first/JSON/include/JSON/Object.hpp +++ b/deps/first/JSON/include/JSON/Object.hpp @@ -14,6 +14,9 @@ #include #include +#include +#include + namespace RC::JSON { class RC_JSON_API Object : public Value @@ -69,7 +72,7 @@ namespace RC::JSON auto value = find_value_by_key(key); if (!value) { - throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; + throw std::runtime_error{to_string(fmt::format(STR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } @@ -80,7 +83,7 @@ namespace RC::JSON auto value = find_value_by_key(key); if (!value) { - throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; + throw std::runtime_error{to_string(fmt::format(STR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } diff --git a/deps/first/JSON/src/Object.cpp b/deps/first/JSON/src/Object.cpp index e4c1c265b..8bcfc35f8 100644 --- a/deps/first/JSON/src/Object.cpp +++ b/deps/first/JSON/src/Object.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include + namespace RC::JSON { auto Object::find_value_by_key(const StringType& look_for_key) const -> Value* @@ -87,7 +90,7 @@ namespace RC::JSON indent(indent_level, object_as_string); } - object_as_string.append(std::format(STR("\"{}\":"), key)); + object_as_string.append(fmt::format(STR("\"{}\":"), key)); object_as_string.append(value->serialize(should_format, indent_level)); if (member_count + 1 < m_members.size()) diff --git a/deps/first/JSON/src/Parser/TokenParser.cpp b/deps/first/JSON/src/Parser/TokenParser.cpp index df0b83912..91ba8a842 100644 --- a/deps/first/JSON/src/Parser/TokenParser.cpp +++ b/deps/first/JSON/src/Parser/TokenParser.cpp @@ -185,7 +185,7 @@ namespace RC::JSON::Parser { do_comma_verification(); - m_last_value = std::make_unique(std::stoll(data_no_spaces, nullptr)); + m_last_value = std::make_unique(std::stoll(to_string(data_no_spaces), nullptr)); } else if (!m_string_started) { diff --git a/deps/first/JSON/src/String.cpp b/deps/first/JSON/src/String.cpp index 5001c7c2c..eaeba3dbc 100644 --- a/deps/first/JSON/src/String.cpp +++ b/deps/first/JSON/src/String.cpp @@ -1,5 +1,8 @@ #include +#include +#include + namespace RC::JSON { String::String(StringViewType string) : m_data(string) @@ -8,6 +11,6 @@ namespace RC::JSON auto String::serialize([[maybe_unused]] ShouldFormat should_format, [[maybe_unused]] int32_t* indent_level) -> StringType { - return std::format(STR("\"{}\""), m_data); + return fmt::format(STR("\"{}\""), m_data); } } // namespace RC::JSON diff --git a/deps/first/LuaMadeSimple/include/LuaMadeSimple/LuaMadeSimple.hpp b/deps/first/LuaMadeSimple/include/LuaMadeSimple/LuaMadeSimple.hpp index c9f8f6bd8..dabb37263 100644 --- a/deps/first/LuaMadeSimple/include/LuaMadeSimple/LuaMadeSimple.hpp +++ b/deps/first/LuaMadeSimple/include/LuaMadeSimple/LuaMadeSimple.hpp @@ -519,8 +519,10 @@ namespace RC::LuaMadeSimple RC_LMS_API auto execute_file(std::string_view) const -> void; RC_LMS_API auto execute_file(std::wstring_view) const -> void; + RC_LMS_API auto execute_file(std::u16string_view) const -> void; RC_LMS_API auto execute_string(std::string_view) const -> void; RC_LMS_API auto execute_string(std::wstring_view) const -> void; + RC_LMS_API auto execute_string(std::u16string_view) const -> void; RC_LMS_API auto open_all_libs() const -> void; RC_LMS_API auto set_hook(lua_Hook, int32_t mask, int32_t count) const -> void; diff --git a/deps/first/LuaMadeSimple/src/LuaMadeSimple.cpp b/deps/first/LuaMadeSimple/src/LuaMadeSimple.cpp index 5106a2449..7f4675a3a 100644 --- a/deps/first/LuaMadeSimple/src/LuaMadeSimple.cpp +++ b/deps/first/LuaMadeSimple/src/LuaMadeSimple.cpp @@ -4,6 +4,8 @@ #include #include +#include + namespace RC::LuaMadeSimple { // All lua instances, lua_State* are stored in the Lua class @@ -435,10 +437,14 @@ namespace RC::LuaMadeSimple auto Lua::execute_file(std::wstring_view file_name_and_path) const -> void { -#pragma warning(disable : 4244) - std::string file_name_and_path_ansi = std::string(file_name_and_path.begin(), file_name_and_path.end()); -#pragma warning(default : 4244) - execute_file(file_name_and_path_ansi); + std::string file_name_and_path_utf8 = to_string(file_name_and_path); + execute_file(file_name_and_path_utf8); + } + + auto Lua::execute_file(std::u16string_view file_name_and_path) const -> void + { + std::string file_name_and_path_utf8 = to_string(file_name_and_path); + execute_file(file_name_and_path_utf8); } auto Lua::execute_string(std::string_view code) const -> void @@ -456,10 +462,14 @@ namespace RC::LuaMadeSimple auto Lua::execute_string(std::wstring_view code) const -> void { -#pragma warning(disable : 4244) - std::string code_ansi = std::string(code.begin(), code.end()); -#pragma warning(default : 4244) - execute_string(code_ansi); + std::string code_utf8 = to_string(code); + execute_string(code_utf8); + } + + auto Lua::execute_string(std::u16string_view code) const -> void + { + std::string code_utf8 = to_string(code); + execute_string(code_utf8); } auto Lua::open_all_libs() const -> void diff --git a/deps/first/LuaMadeSimple/xmake.lua b/deps/first/LuaMadeSimple/xmake.lua index 441939d43..481a4fe60 100644 --- a/deps/first/LuaMadeSimple/xmake.lua +++ b/deps/first/LuaMadeSimple/xmake.lua @@ -12,4 +12,5 @@ target(projectName) add_files("src/**.cpp") add_deps("LuaRaw", { public = true }) + add_deps("Helpers") add_packages("fmt") \ No newline at end of file diff --git a/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp b/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp index 1ea87a5f7..c2e71995d 100644 --- a/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp +++ b/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace RC::ParserBase { class Token; diff --git a/deps/first/ParserBase/src/Tokenizer.cpp b/deps/first/ParserBase/src/Tokenizer.cpp index 40e57bfec..0ac017143 100644 --- a/deps/first/ParserBase/src/Tokenizer.cpp +++ b/deps/first/ParserBase/src/Tokenizer.cpp @@ -122,7 +122,7 @@ namespace RC::ParserBase { TokenFoundWrapper token_found{}; - if (c && *c == L'\n') + if (c && *c == STR('\n')) { ++m_current_line; m_current_column = 0; diff --git a/deps/first/String/include/String/StringType.hpp b/deps/first/String/include/String/StringType.hpp index 44f4d6170..889395566 100644 --- a/deps/first/String/include/String/StringType.hpp +++ b/deps/first/String/include/String/StringType.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include // We will use this once we solve the circular dependency issue //#include @@ -24,4 +25,30 @@ namespace RC { using StringViewType = std::basic_string_view; using StreamIType = std::basic_ifstream; using StreamOType = std::basic_ofstream; + + // convert a T* pointer to a CharType* pointer and keep the alignment and constness if the size of the types is the same + template + auto static ToCharTypePtr(T* ptr) { + static_assert(sizeof(T) == sizeof(CharType), "Sizes of T and CharType must be the same"); + + using CharPtrType = std::conditional_t< + std::is_const_v, + const CharType, + CharType + >*; + + return reinterpret_cast(ptr); + } + + template + auto static FromCharTypePtr(CharT* ptr) { + static_assert(sizeof(T) == sizeof(CharType), "Sizes of T and CharType must be the same"); + static_assert(std::is_same_v, CharType>, "Must be a CharType"); + using TargetPtrType = std::conditional_t< + std::is_const_v, + const T, + T + >*; + return reinterpret_cast(ptr); + } } // namespace RC diff --git a/deps/first/Unreal b/deps/first/Unreal index 32908ddf6..a4f9b7b26 160000 --- a/deps/first/Unreal +++ b/deps/first/Unreal @@ -1 +1 @@ -Subproject commit 32908ddf683ebe68a415d0b81cdc023d42002bf0 +Subproject commit a4f9b7b2679b0e33833b563e1e1e50d166112874