fix Tethealla client detection

This commit is contained in:
Martin Michelsen
2024-05-13 21:55:32 -07:00
parent cb9a0ed1c4
commit 79efce5252
2 changed files with 41 additions and 38 deletions
+1 -38
View File
@@ -1001,37 +1001,6 @@ static void on_9E_XB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
}
}
static void scramble_bb_security_data(parray<uint8_t, 0x28>& data, uint8_t which, bool reverse) {
static const uint8_t forward_orders[8][5] = {
{2, 0, 1, 4, 3},
{3, 4, 0, 1, 2},
{2, 3, 4, 0, 1},
{2, 3, 0, 1, 4},
{0, 2, 3, 4, 1},
{1, 4, 2, 3, 0},
{2, 0, 1, 4, 3},
{1, 0, 3, 4, 2},
};
static const uint8_t reverse_orders[8][5] = {
{1, 2, 0, 4, 3},
{2, 3, 4, 0, 1},
{3, 4, 0, 1, 2},
{2, 3, 0, 1, 4},
{0, 4, 1, 2, 3},
{4, 0, 2, 3, 1},
{1, 2, 0, 4, 3},
{1, 0, 4, 2, 3},
};
const auto& order = reverse ? reverse_orders[which & 7] : forward_orders[which & 7];
parray<uint8_t, 0x28> scrambled_data;
for (size_t z = 0; z < 5; z++) {
for (size_t x = 0; x < 8; x++) {
scrambled_data[(z * 8) + x] = data[(order[z] * 8) + x];
}
}
data = scrambled_data;
}
static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
const auto& base_cmd = check_size_t<C_LoginBase_BB_93>(data, 0xFFFF);
auto s = c->require_server_state();
@@ -1040,12 +1009,6 @@ static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
? check_size_t<C_LoginWithoutHardwareInfo_BB_93>(data).client_config
: check_size_t<C_LoginWithHardwareInfo_BB_93>(data).client_config;
// If security_token is zero, the game scrambles the client config data based
// on the first character in the username. We undo the scramble here.
if (base_cmd.security_token == 0) {
scramble_bb_security_data(config_data, base_cmd.username.at(0), true);
}
c->config.set_flags_for_version(c->version(), base_cmd.sub_version);
c->channel.language = base_cmd.language;
string username = base_cmd.username.decode();
@@ -1075,7 +1038,7 @@ static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
// 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.")) {
if (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.
+40
View File
@@ -564,6 +564,37 @@ void send_pc_console_split_reconnect(shared_ptr<Client> c, uint32_t address,
send_command_t(c, 0x19, 0x00, cmd);
}
static void scramble_bb_security_data(parray<uint8_t, 0x28>& data, uint8_t which, bool reverse) {
static const uint8_t forward_orders[8][5] = {
{2, 0, 1, 4, 3},
{3, 4, 0, 1, 2},
{2, 3, 4, 0, 1},
{2, 3, 0, 1, 4},
{0, 2, 3, 4, 1},
{1, 4, 2, 3, 0},
{2, 0, 1, 4, 3},
{1, 0, 3, 4, 2},
};
static const uint8_t reverse_orders[8][5] = {
{1, 2, 0, 4, 3},
{2, 3, 4, 0, 1},
{3, 4, 0, 1, 2},
{2, 3, 0, 1, 4},
{0, 4, 1, 2, 3},
{4, 0, 2, 3, 1},
{1, 2, 0, 4, 3},
{1, 0, 4, 2, 3},
};
const auto& order = reverse ? reverse_orders[which & 7] : forward_orders[which & 7];
parray<uint8_t, 0x28> scrambled_data;
for (size_t z = 0; z < 5; z++) {
for (size_t x = 0; x < 8; x++) {
scrambled_data[(z * 8) + x] = data[(order[z] * 8) + x];
}
}
data = scrambled_data;
}
void send_client_init_bb(shared_ptr<Client> c, uint32_t error_code) {
auto team = c->team();
S_ClientInit_BB_00E6 cmd;
@@ -574,6 +605,15 @@ void send_client_init_bb(shared_ptr<Client> c, uint32_t error_code) {
c->config.serialize_into(cmd.client_config);
cmd.can_create_team = 1;
cmd.episode_4_unlocked = 1;
// If security_token is zero, the game scrambles the client config data based
// on the first character in the username. We undo the scramble here, so when
// the client scrambles the data upon receipt, it will be correct when it next
// is sent back to the server.
if (cmd.security_token == 0 && c->login && c->login->bb_license) {
scramble_bb_security_data(cmd.client_config, c->login->bb_license->username.at(0), true);
}
send_command_t(c, 0x00E6, 0x00000000, cmd);
}