fix Tethealla client detection
This commit is contained in:
+1
-38
@@ -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) {
|
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);
|
const auto& base_cmd = check_size_t<C_LoginBase_BB_93>(data, 0xFFFF);
|
||||||
auto s = c->require_server_state();
|
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_LoginWithoutHardwareInfo_BB_93>(data).client_config
|
||||||
: check_size_t<C_LoginWithHardwareInfo_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->config.set_flags_for_version(c->version(), base_cmd.sub_version);
|
||||||
c->channel.language = base_cmd.language;
|
c->channel.language = base_cmd.language;
|
||||||
string username = base_cmd.username.decode();
|
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,
|
// normal version encoding logic. Otherwise, assume it's a community mod,
|
||||||
// almost all of which are based on TethVer12513, so assume that version
|
// almost all of which are based on TethVer12513, so assume that version
|
||||||
// otherwise.
|
// otherwise.
|
||||||
if (true || starts_with(version_string, "Ver.")) {
|
if (starts_with(version_string, "Ver.")) {
|
||||||
// Basic algorithm: take all numeric characters from the version string
|
// Basic algorithm: take all numeric characters from the version string
|
||||||
// and ignore everything else. Treat that as a decimal integer, then
|
// and ignore everything else. Treat that as a decimal integer, then
|
||||||
// base36-encode it into the low 3 bytes of specific_version.
|
// base36-encode it into the low 3 bytes of specific_version.
|
||||||
|
|||||||
@@ -564,6 +564,37 @@ void send_pc_console_split_reconnect(shared_ptr<Client> c, uint32_t address,
|
|||||||
send_command_t(c, 0x19, 0x00, cmd);
|
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) {
|
void send_client_init_bb(shared_ptr<Client> c, uint32_t error_code) {
|
||||||
auto team = c->team();
|
auto team = c->team();
|
||||||
S_ClientInit_BB_00E6 cmd;
|
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);
|
c->config.serialize_into(cmd.client_config);
|
||||||
cmd.can_create_team = 1;
|
cmd.can_create_team = 1;
|
||||||
cmd.episode_4_unlocked = 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);
|
send_command_t(c, 0x00E6, 0x00000000, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user