| 997 | } |
| 998 | |
| 999 | void Patch::PatchFunc::dpatch(PatchGroup* group, const std::string_view cmd, const std::string_view param) |
| 1000 | { |
| 1001 | #define PATCH_ERROR(fstring, ...) \ |
| 1002 | Console.Error(fmt::format("(dPatch) Error Parsing: {}={}: " fstring, cmd, param, __VA_ARGS__)) |
| 1003 | |
| 1004 | // [0]=version/type,[1]=number of patterns,[2]=number of replacements |
| 1005 | // Each pattern or replacement is [3]=offset,[4]=hex |
| 1006 | |
| 1007 | const std::vector<std::string_view> pieces(StringUtil::SplitString(param, ',', false)); |
| 1008 | if (pieces.size() < 3) |
| 1009 | { |
| 1010 | PATCH_ERROR("Expected at least 3 data parameters; only found {}", pieces.size()); |
| 1011 | return; |
| 1012 | } |
| 1013 | |
| 1014 | |
| 1015 | std::string_view patterns_end, replacements_end; |
| 1016 | |
| 1017 | // Implemented for possible future use so we don't have to break backcompat |
| 1018 | std::optional<u32> dpatch_type = StringUtil::FromChars<u32>(pieces[0]); |
| 1019 | |
| 1020 | std::optional<u32> num_patterns = StringUtil::FromChars<u32>(pieces[1], 16, &patterns_end); |
| 1021 | std::optional<u32> num_replacements = StringUtil::FromChars<u32>(pieces[2], 16, &replacements_end); |
| 1022 | |
| 1023 | if (!dpatch_type.has_value()) |
| 1024 | { |
| 1025 | PATCH_ERROR("Malformed version/type '{}', a decimal number(e.g. 0,1,2) is expected", pieces[0]); |
| 1026 | return; |
| 1027 | } |
| 1028 | |
| 1029 | if (dpatch_type.value() != 0) |
| 1030 | { |
| 1031 | PATCH_ERROR("Unsupported version/type '{}', only 0 is currently supported", pieces[0]); |
| 1032 | return; |
| 1033 | } |
| 1034 | |
| 1035 | if (!num_patterns.has_value()) |
| 1036 | { |
| 1037 | PATCH_ERROR("Malformed number of patterns '{}', a decimal number is expected", pieces[1]); |
| 1038 | return; |
| 1039 | } |
| 1040 | |
| 1041 | if (!num_replacements.has_value()) |
| 1042 | { |
| 1043 | PATCH_ERROR("Malformed number of replacements '{}', a decimal number is expected", pieces[2]); |
| 1044 | return; |
| 1045 | } |
| 1046 | |
| 1047 | if (pieces.size() != ((num_patterns.value() * 2) + (num_replacements.value() * 2) + 3)) |
| 1048 | { |
| 1049 | PATCH_ERROR("Expected 2 fields for each {} patterns and {} replacements; found {}", num_patterns.value(), num_replacements.value(), pieces.size() - 2); |
| 1050 | return; |
| 1051 | } |
| 1052 | |
| 1053 | DynamicPatch dpatch; |
| 1054 | for (u32 i = 0; i < num_patterns.value(); i++) |
| 1055 | { |
| 1056 | std::optional<u32> offset = StringUtil::FromChars<u32>(pieces[3 + (i * 2)], 16); |
nothing calls this directly
no test coverage detected