don't save licenses for replay sessions
This commit is contained in:
+68
-55
@@ -53,17 +53,8 @@ JSON License::json() const {
|
||||
});
|
||||
}
|
||||
|
||||
void License::save() const {
|
||||
auto json = this->json();
|
||||
string json_data = json.serialize(JSON::SerializeOption::FORMAT | JSON::SerializeOption::HEX_INTEGERS);
|
||||
string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number);
|
||||
save_file(filename, json_data);
|
||||
}
|
||||
|
||||
void License::delete_file() const {
|
||||
string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number);
|
||||
remove(filename.c_str());
|
||||
}
|
||||
void License::save() const {}
|
||||
void License::delete_file() const {}
|
||||
|
||||
string License::str() const {
|
||||
vector<string> tokens;
|
||||
@@ -102,53 +93,22 @@ string License::str() const {
|
||||
return "[License: " + join(tokens, ", ") + "]";
|
||||
}
|
||||
|
||||
struct BinaryLicense {
|
||||
pstring<TextEncoding::ASCII, 0x14> username; // BB username (max. 16 chars; should technically be Unicode)
|
||||
pstring<TextEncoding::ASCII, 0x14> bb_password; // BB password (max. 16 chars)
|
||||
uint32_t serial_number; // PC/GC serial number. MUST BE PRESENT FOR BB LICENSES TOO; this is also the player's guild card number.
|
||||
pstring<TextEncoding::ASCII, 0x10> access_key; // PC/GC access key. (to log in using PC on a GC license, just enter the first 8 characters of the GC access key)
|
||||
pstring<TextEncoding::ASCII, 0x0C> gc_password; // GC password
|
||||
uint32_t privileges; // privilege level
|
||||
uint64_t ban_end_time; // end time of ban (zero = not banned)
|
||||
} __attribute__((packed));
|
||||
DiskLicense::DiskLicense(const JSON& json) : License(json) {}
|
||||
|
||||
LicenseIndex::LicenseIndex() {
|
||||
if (!isdir("system/licenses")) {
|
||||
mkdir("system/licenses", 0755);
|
||||
}
|
||||
void DiskLicense::save() const {
|
||||
auto json = this->json();
|
||||
string json_data = json.serialize(JSON::SerializeOption::FORMAT | JSON::SerializeOption::HEX_INTEGERS);
|
||||
string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number);
|
||||
save_file(filename, json_data);
|
||||
}
|
||||
|
||||
// Convert binary licenses to JSON licenses and save them
|
||||
if (isfile("system/licenses.nsi")) {
|
||||
auto bin_licenses = load_vector_file<BinaryLicense>("system/licenses.nsi");
|
||||
for (const auto& bin_license : bin_licenses) {
|
||||
// Only add licenses from the binary file if there isn't a JSON version of
|
||||
// the same license
|
||||
try {
|
||||
this->get(bin_license.serial_number);
|
||||
} catch (const missing_license&) {
|
||||
License license;
|
||||
license.serial_number = bin_license.serial_number;
|
||||
license.access_key = bin_license.access_key.decode();
|
||||
license.gc_password = bin_license.gc_password.decode();
|
||||
license.bb_username = bin_license.username.decode();
|
||||
license.bb_password = bin_license.bb_password.decode();
|
||||
license.flags = bin_license.privileges;
|
||||
license.ban_end_time = bin_license.ban_end_time;
|
||||
license.ep3_current_meseta = 0;
|
||||
license.ep3_total_meseta_earned = 0;
|
||||
license.save();
|
||||
}
|
||||
}
|
||||
::remove("system/licenses.nsi");
|
||||
}
|
||||
void DiskLicense::delete_file() const {
|
||||
string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number);
|
||||
remove(filename.c_str());
|
||||
}
|
||||
|
||||
for (const auto& item : list_directory("system/licenses")) {
|
||||
if (ends_with(item, ".json")) {
|
||||
JSON json = JSON::parse(load_file("system/licenses/" + item));
|
||||
auto license = make_shared<License>(json);
|
||||
this->add(license);
|
||||
}
|
||||
}
|
||||
shared_ptr<License> LicenseIndex::create_license() const {
|
||||
return make_shared<License>();
|
||||
}
|
||||
|
||||
size_t LicenseIndex::count() const {
|
||||
@@ -288,3 +248,56 @@ shared_ptr<License> LicenseIndex::verify_bb(const string& username, const string
|
||||
throw missing_license();
|
||||
}
|
||||
}
|
||||
|
||||
DiskLicenseIndex::DiskLicenseIndex() {
|
||||
struct BinaryLicense {
|
||||
pstring<TextEncoding::ASCII, 0x14> username; // BB username (max. 16 chars; should technically be Unicode)
|
||||
pstring<TextEncoding::ASCII, 0x14> bb_password; // BB password (max. 16 chars)
|
||||
uint32_t serial_number; // PC/GC serial number. MUST BE PRESENT FOR BB LICENSES TOO; this is also the player's guild card number.
|
||||
pstring<TextEncoding::ASCII, 0x10> access_key; // PC/GC access key. (to log in using PC on a GC license, just enter the first 8 characters of the GC access key)
|
||||
pstring<TextEncoding::ASCII, 0x0C> gc_password; // GC password
|
||||
uint32_t privileges; // privilege level
|
||||
uint64_t ban_end_time; // end time of ban (zero = not banned)
|
||||
} __attribute__((packed));
|
||||
|
||||
if (!isdir("system/licenses")) {
|
||||
mkdir("system/licenses", 0755);
|
||||
}
|
||||
|
||||
// Convert binary licenses to JSON licenses and save them
|
||||
if (isfile("system/licenses.nsi")) {
|
||||
auto bin_licenses = load_vector_file<BinaryLicense>("system/licenses.nsi");
|
||||
for (const auto& bin_license : bin_licenses) {
|
||||
// Only add licenses from the binary file if there isn't a JSON version of
|
||||
// the same license
|
||||
try {
|
||||
this->get(bin_license.serial_number);
|
||||
} catch (const missing_license&) {
|
||||
License license;
|
||||
license.serial_number = bin_license.serial_number;
|
||||
license.access_key = bin_license.access_key.decode();
|
||||
license.gc_password = bin_license.gc_password.decode();
|
||||
license.bb_username = bin_license.username.decode();
|
||||
license.bb_password = bin_license.bb_password.decode();
|
||||
license.flags = bin_license.privileges;
|
||||
license.ban_end_time = bin_license.ban_end_time;
|
||||
license.ep3_current_meseta = 0;
|
||||
license.ep3_total_meseta_earned = 0;
|
||||
license.save();
|
||||
}
|
||||
}
|
||||
::remove("system/licenses.nsi");
|
||||
}
|
||||
|
||||
for (const auto& item : list_directory("system/licenses")) {
|
||||
if (ends_with(item, ".json")) {
|
||||
JSON json = JSON::parse(load_file("system/licenses/" + item));
|
||||
auto license = make_shared<DiskLicense>(json);
|
||||
this->add(license);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<License> DiskLicenseIndex::create_license() const {
|
||||
return make_shared<DiskLicense>();
|
||||
}
|
||||
|
||||
+27
-5
@@ -10,7 +10,8 @@
|
||||
|
||||
class LicenseIndex;
|
||||
|
||||
struct License {
|
||||
class License {
|
||||
public:
|
||||
enum Flag : uint32_t {
|
||||
// clang-format off
|
||||
KICK_USER = 0x00000001,
|
||||
@@ -53,14 +54,25 @@ struct License {
|
||||
|
||||
License() = default;
|
||||
explicit License(const JSON& json);
|
||||
virtual ~License() = default;
|
||||
|
||||
JSON json() const;
|
||||
void save() const;
|
||||
void delete_file() const;
|
||||
virtual void save() const;
|
||||
virtual void delete_file() const;
|
||||
|
||||
std::string str() const;
|
||||
};
|
||||
|
||||
class DiskLicense : public License {
|
||||
public:
|
||||
DiskLicense() = default;
|
||||
explicit DiskLicense(const JSON& json);
|
||||
virtual ~DiskLicense() = default;
|
||||
|
||||
virtual void save() const;
|
||||
virtual void delete_file() const;
|
||||
};
|
||||
|
||||
class LicenseIndex {
|
||||
public:
|
||||
class no_username : public std::invalid_argument {
|
||||
@@ -80,8 +92,10 @@ public:
|
||||
missing_license() : invalid_argument("missing license") {}
|
||||
};
|
||||
|
||||
LicenseIndex();
|
||||
~LicenseIndex() = default;
|
||||
LicenseIndex() = default;
|
||||
virtual ~LicenseIndex() = default;
|
||||
|
||||
virtual std::shared_ptr<License> create_license() const;
|
||||
|
||||
size_t count() const;
|
||||
std::shared_ptr<License> get(uint32_t serial_number) const;
|
||||
@@ -101,3 +115,11 @@ protected:
|
||||
std::unordered_map<std::string, std::shared_ptr<License>> xb_gamertag_to_license;
|
||||
std::unordered_map<uint32_t, std::shared_ptr<License>> serial_number_to_license;
|
||||
};
|
||||
|
||||
class DiskLicenseIndex : public LicenseIndex {
|
||||
public:
|
||||
DiskLicenseIndex();
|
||||
virtual ~DiskLicenseIndex() = default;
|
||||
|
||||
virtual std::shared_ptr<License> create_license() const;
|
||||
};
|
||||
|
||||
+1
-1
@@ -377,7 +377,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
if (!s->allow_unregistered_users) {
|
||||
throw;
|
||||
}
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||
l->bb_username = cmd.username.decode();
|
||||
l->bb_password = cmd.password.decode();
|
||||
|
||||
+11
-11
@@ -412,7 +412,7 @@ static void on_DB_V3(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
l->gc_password = cmd.password.decode();
|
||||
@@ -456,7 +456,7 @@ static void on_88_DCNTE(shared_ptr<Client> c, uint16_t, uint32_t, string& data)
|
||||
send_message_box(c, "Incorrect serial number");
|
||||
c->should_disconnect = true;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -499,7 +499,7 @@ static void on_8B_DCNTE(shared_ptr<Client> c, uint16_t, uint32_t, string& data)
|
||||
send_message_box(c, "Incorrect serial number");
|
||||
c->should_disconnect = true;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -553,7 +553,7 @@ static void on_90_DC(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
send_command(c, 0x90, 0x03);
|
||||
c->should_disconnect = true;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -610,7 +610,7 @@ static void on_93_DC(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -699,7 +699,7 @@ static void on_9A(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else if (is_v1_or_v2(c->version())) {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -759,7 +759,7 @@ static void on_9C(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = cmd.access_key.decode();
|
||||
if (is_gc(c->version())) {
|
||||
@@ -878,7 +878,7 @@ static void on_9D_9E(shared_ptr<Client> c, uint16_t command, uint32_t, string& d
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else if (is_v1_or_v2(c->version())) {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = serial_number;
|
||||
l->access_key = base_cmd->access_key.decode();
|
||||
s->license_index->add(l);
|
||||
@@ -947,7 +947,7 @@ static void on_9E_XB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
return;
|
||||
|
||||
} catch (const LicenseIndex::missing_license& e) {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = fnv1a32(xb_gamertag) & 0x7FFFFFFF;
|
||||
l->xb_gamertag = xb_gamertag;
|
||||
l->xb_user_id = xb_user_id;
|
||||
@@ -1004,7 +1004,7 @@ static void on_93_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
c->should_disconnect = true;
|
||||
return;
|
||||
} else {
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||
l->bb_username = cmd.username.decode();
|
||||
l->bb_password = cmd.password.decode();
|
||||
@@ -4893,7 +4893,7 @@ static void on_04_P(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
return;
|
||||
} else {
|
||||
|
||||
auto l = make_shared<License>();
|
||||
auto l = s->license_index->create_license();
|
||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||
l->bb_username = cmd.username.decode();
|
||||
l->bb_password = cmd.password.decode();
|
||||
|
||||
+3
-2
@@ -321,7 +321,7 @@ Proxy session commands:\n\
|
||||
}
|
||||
|
||||
} else if (command_name == "add-license") {
|
||||
auto l = make_shared<License>();
|
||||
auto l = this->state->license_index->create_license();
|
||||
|
||||
for (const string& token : split(command_args, ' ')) {
|
||||
if (starts_with(token, "bb-username=")) {
|
||||
@@ -376,7 +376,8 @@ Proxy session commands:\n\
|
||||
uint32_t serial_number = stoul(tokens[0]);
|
||||
tokens.erase(tokens.begin());
|
||||
auto orig_l = this->state->license_index->get(serial_number);
|
||||
auto l = make_shared<License>(*orig_l);
|
||||
auto l = this->state->license_index->create_license();
|
||||
*l = *orig_l;
|
||||
|
||||
this->state->license_index->remove(orig_l->serial_number);
|
||||
try {
|
||||
|
||||
+1
-1
@@ -973,7 +973,7 @@ void ServerState::load_bb_private_keys() {
|
||||
|
||||
void ServerState::load_licenses() {
|
||||
config_log.info("Indexing licenses");
|
||||
this->license_index = make_shared<LicenseIndex>();
|
||||
this->license_index = this->is_replay ? make_shared<LicenseIndex>() : make_shared<DiskLicenseIndex>();
|
||||
}
|
||||
|
||||
void ServerState::load_teams() {
|
||||
|
||||
Reference in New Issue
Block a user