support B2 patches on BB
This commit is contained in:
@@ -392,8 +392,9 @@ shared_ptr<const Menu> FunctionCodeIndex::patch_switches_menu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionCodeIndex::patch_menu_empty(uint32_t specific_version) const {
|
bool FunctionCodeIndex::patch_menu_empty(uint32_t specific_version) const {
|
||||||
|
uint32_t mask = specific_version_is_indeterminate(specific_version) ? 0xFF000000 : 0xFFFFFFFF;
|
||||||
for (const auto& it : this->menu_item_id_and_specific_version_to_patch_function) {
|
for (const auto& it : this->menu_item_id_and_specific_version_to_patch_function) {
|
||||||
if ((it.first & 0xFF000000) == (specific_version & 0xFF000000)) {
|
if ((it.first & mask) == (specific_version & mask)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1071,6 +1071,48 @@ static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
|||||||
} else {
|
} else {
|
||||||
string version_string = config_data.as_string();
|
string version_string = config_data.as_string();
|
||||||
strip_trailing_zeroes(version_string);
|
strip_trailing_zeroes(version_string);
|
||||||
|
// If the version string starts with "Ver.", assume it's Sega and apply the
|
||||||
|
// normal version encoding logic. Otherwise, assume it's a community mod,
|
||||||
|
// almost all of which are based on TethVer12513, so assume that version
|
||||||
|
// otherwise.
|
||||||
|
if (true || starts_with(version_string, "Ver.")) {
|
||||||
|
// Basic algorithm: take all numeric characters from the version string
|
||||||
|
// and ignore everything else. Treat that as a decimal integer, then
|
||||||
|
// base36-encode it into the low 3 bytes of specific_version.
|
||||||
|
uint64_t version = 0;
|
||||||
|
for (char ch : version_string) {
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
version = (version * 10) + (ch - '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t shift = 0;
|
||||||
|
uint32_t specific_version = 0;
|
||||||
|
while (version) {
|
||||||
|
if (shift > 16) {
|
||||||
|
throw runtime_error("invalid version string");
|
||||||
|
}
|
||||||
|
uint8_t ch = (version % 36) + '0';
|
||||||
|
version /= 36;
|
||||||
|
if (ch > '9') {
|
||||||
|
ch += 7;
|
||||||
|
}
|
||||||
|
specific_version |= (ch << shift);
|
||||||
|
shift += 8;
|
||||||
|
}
|
||||||
|
if (!(specific_version & 0x00FF0000)) {
|
||||||
|
specific_version |= 0x00300000;
|
||||||
|
}
|
||||||
|
if (!(specific_version & 0x0000FF00)) {
|
||||||
|
specific_version |= 0x00003000;
|
||||||
|
}
|
||||||
|
if (!(specific_version & 0x000000FF)) {
|
||||||
|
specific_version |= 0x00000030;
|
||||||
|
}
|
||||||
|
c->config.specific_version = 0x35000000 | specific_version;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
c->config.specific_version = 0x35394E4C; // 59NL
|
||||||
|
|
||||||
// Note: Tethealla PSOBB is actually Japanese PSOBB, but with most of the
|
// Note: Tethealla PSOBB is actually Japanese PSOBB, but with most of the
|
||||||
// files replaced with English text/graphics/etc. For this reason, it still
|
// files replaced with English text/graphics/etc. For this reason, it still
|
||||||
// reports its language as Japanese, so we have to account for that
|
// reports its language as Japanese, so we have to account for that
|
||||||
@@ -1080,6 +1122,7 @@ static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
|||||||
c->config.set_flag(Client::Flag::FORCE_ENGLISH_LANGUAGE_BB);
|
c->config.set_flag(Client::Flag::FORCE_ENGLISH_LANGUAGE_BB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c->channel.language = c->config.check_flag(Client::Flag::FORCE_ENGLISH_LANGUAGE_BB) ? 1 : base_cmd.language;
|
c->channel.language = c->config.check_flag(Client::Flag::FORCE_ENGLISH_LANGUAGE_BB) ? 1 : base_cmd.language;
|
||||||
c->bb_connection_phase = base_cmd.connection_phase;
|
c->bb_connection_phase = base_cmd.connection_phase;
|
||||||
c->bb_character_index = base_cmd.character_slot;
|
c->bb_character_index = base_cmd.character_slot;
|
||||||
|
|||||||
+2
-4
@@ -305,10 +305,8 @@ bool specific_version_is_xb(uint32_t specific_version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool specific_version_is_bb(uint32_t specific_version) {
|
bool specific_version_is_bb(uint32_t specific_version) {
|
||||||
// TODO: We should actually find a way to determine BB specific_versions, but
|
// BB specific_versions are 5XXX, where X is an encoding of the revision number
|
||||||
// there are so many mods out there, and there's a patch server anyway, so it
|
return (specific_version & 0xFF000000) == 0x35000000;
|
||||||
// seems not worth the effort
|
|
||||||
return specific_version == 0x35303030;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* file_path_token_for_version(Version version) {
|
const char* file_path_token_for_version(Version version) {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
start:
|
||||||
|
push ebx
|
||||||
|
jmp get_patch_data_ptr
|
||||||
|
get_patch_data_ptr_ret:
|
||||||
|
pop ebx # ebx = patch header
|
||||||
|
|
||||||
|
apply_next_patch:
|
||||||
|
cmp dword [ebx + 4], 0
|
||||||
|
jne copy_code_and_apply_again
|
||||||
|
pop ebx
|
||||||
|
mov eax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
copy_code_and_apply_again:
|
||||||
|
xor ecx, ecx # ecx = offset
|
||||||
|
mov edx, [ebx] # edx = dest addr
|
||||||
|
copy_next_byte:
|
||||||
|
mov al, [ebx + ecx + 8] # copy one byte to dest
|
||||||
|
mov [edx + ecx], al
|
||||||
|
inc ecx # offset++
|
||||||
|
cmp [ebx + 4], ecx # check if all bytes have been copied
|
||||||
|
jne copy_next_byte
|
||||||
|
|
||||||
|
lea ebx, [ebx + ecx + 8] # advance to next block
|
||||||
|
jmp apply_next_patch
|
||||||
|
|
||||||
|
get_patch_data_ptr:
|
||||||
|
call get_patch_data_ptr_ret
|
||||||
|
first_patch_header:
|
||||||
Reference in New Issue
Block a user