File tree Expand file tree Collapse file tree 4 files changed +60
-23
lines changed
Expand file tree Collapse file tree 4 files changed +60
-23
lines changed Original file line number Diff line number Diff line change @@ -56,17 +56,16 @@ namespace RC
5656 mods_directories.insert (mods_directories.begin (), std::filesystem::path{Overrides.ModsFolderPath });
5757 }
5858
59- auto mods_paths_add_list = parser.get_ordered_list (STR (" Overrides.ModsFolderPaths.Add" ));
60- mods_paths_add_list.for_each ([](uint32_t i, const StringType& item) {
61- // Add if not already in the list.
62- // Moves to the bottom of the list if it already exists.
63- UE4SSProgram::get_program ().add_mods_directory (item);
64- });
65-
66- auto mods_paths_remove_list = parser.get_ordered_list (STR (" Overrides.ModsFolderPaths.Remove" ));
67- mods_paths_remove_list.for_each ([](uint32_t i, const StringType& item) {
68- // Removes if it exists in the list.
69- UE4SSProgram::get_program ().remove_mods_directory (item);
59+ auto mods_paths_list = parser.get_list (section_overrides);
60+ mods_paths_list.for_each (STR (" ModsFolderPaths" ), [](const StringType& key, const Ini::Value& value) {
61+ if (key.starts_with (STR (' +' )))
62+ {
63+ UE4SSProgram::get_program ().add_mods_directory (value.get_string_value ());
64+ }
65+ else if (key.starts_with (STR (' -' )))
66+ {
67+ UE4SSProgram::get_program ().remove_mods_directory (value.get_string_value ());
68+ }
7069 });
7170
7271 constexpr static File::CharType section_general[] = STR (" General" );
Original file line number Diff line number Diff line change 33; Default: <dll_directory>/Mods
44ModsFolderPath =
55
6- [Overrides.ModsFolderPaths.Add]
76; Additional mods directories to load mods from.
8- ; Spaces are allowed, but do not use quotes!
9- ; Paths can be relative to the working directory (where UE4SS.dll is located), or absolute.
10- ; Mods will be loaded starting from the top of this list, with mods from further down overriding mods from further up.
11- ; The value of 'ModsFolderPath' is automatically inserted as the first value.
7+ ; Use + prefix to add a directory, - prefix to remove.
8+ ; Can be relative to working directory or absolute paths.
9+ ; Note: If multiple directories contain mods with the same name, the last one found will be loaded.
1210; Example:
13- ; ../SharedMods
14- ; C:/MyMods
15- ; Default: None
16-
17- [Overrides.ModsFolderPaths.Remove]
18- ; Remove mods directories to load mods from.
11+ ; +ModsFolderPaths = ../SharedMods
12+ ; +ModsFolderPaths = C:/MyMods
13+ ; -ModsFolderPaths = ../SharedMods
1914; Default: None
2015
2116[General]
Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ namespace RC::Ini
1111 {
1212 std::unordered_map<File::StringType, Value> key_value_pairs{};
1313 std::vector<File::StringType> ordered_list{};
14+ std::vector<std::pair<File::StringType, Value>> key_value_array{};
1415 bool is_ordered_list{};
1516 };
1617
@@ -59,6 +60,40 @@ namespace RC::Ini
5960 }
6061 }
6162 }
63+
64+ template <typename Callable>
65+ auto for_each (const StringType match_key, Callable callable)
66+ {
67+ if (!m_section)
68+ {
69+ return ;
70+ }
71+ if constexpr (CallableWithKeyValuePair<Callable>)
72+ {
73+ for (const auto & [key, value] : m_section->key_value_array )
74+ {
75+ // Skip '+' or '-' when comparing.
76+ StringViewType key_view{key.begin () + 1 , key.end ()};
77+ if (key_view == match_key)
78+ {
79+ callable (key, value);
80+ }
81+ }
82+ }
83+ else
84+ {
85+ for (size_t i = 0 ; i < m_section->key_value_array .size (); ++i)
86+ {
87+ auto [key, value] = m_section->key_value_array [i];
88+ // Skip '+' or '-' when comparing.
89+ StringViewType key_view{key.begin () + 1 , key.end ()};
90+ if (key_view == match_key)
91+ {
92+ callable (i, value.get_string_value ());
93+ }
94+ }
95+ }
96+ }
6297 };
6398
6499 // Backwards compatibility just in case some external code made direct references to 'OrderedList'.
Original file line number Diff line number Diff line change @@ -371,7 +371,15 @@ namespace RC::Ini
371371 }
372372
373373 // Create the value with the correct key and an empty value and store a pointer to it so that the value can be set later
374- m_current_value = &m_current_section->key_value_pairs .emplace (m_current_character_data, Value{}).first ->second ;
374+ if (!m_current_character_data.empty () && (m_current_character_data.starts_with (STR (' +' )) || m_current_character_data.starts_with (STR (' -' ))))
375+ {
376+ // Retaining '+' and '-' for the user to process later.
377+ m_current_value = &m_current_section->key_value_array .emplace_back (m_current_character_data, Value{}).second ;
378+ }
379+ else
380+ {
381+ m_current_value = &m_current_section->key_value_pairs .emplace (m_current_character_data, Value{}).first ->second ;
382+ }
375383 m_current_value->add_string_value (STR (" " ));
376384 m_current_value->set_ref (m_current_value);
377385 m_current_character_data.clear ();
You can’t perform that action at this time.
0 commit comments