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 {
|
void License::save() const {}
|
||||||
auto json = this->json();
|
void License::delete_file() const {}
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
string License::str() const {
|
string License::str() const {
|
||||||
vector<string> tokens;
|
vector<string> tokens;
|
||||||
@@ -102,53 +93,22 @@ string License::str() const {
|
|||||||
return "[License: " + join(tokens, ", ") + "]";
|
return "[License: " + join(tokens, ", ") + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BinaryLicense {
|
DiskLicense::DiskLicense(const JSON& json) : License(json) {}
|
||||||
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));
|
|
||||||
|
|
||||||
LicenseIndex::LicenseIndex() {
|
void DiskLicense::save() const {
|
||||||
if (!isdir("system/licenses")) {
|
auto json = this->json();
|
||||||
mkdir("system/licenses", 0755);
|
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
|
void DiskLicense::delete_file() const {
|
||||||
if (isfile("system/licenses.nsi")) {
|
string filename = string_printf("system/licenses/%010" PRIu32 ".json", this->serial_number);
|
||||||
auto bin_licenses = load_vector_file<BinaryLicense>("system/licenses.nsi");
|
remove(filename.c_str());
|
||||||
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")) {
|
shared_ptr<License> LicenseIndex::create_license() const {
|
||||||
if (ends_with(item, ".json")) {
|
return make_shared<License>();
|
||||||
JSON json = JSON::parse(load_file("system/licenses/" + item));
|
|
||||||
auto license = make_shared<License>(json);
|
|
||||||
this->add(license);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t LicenseIndex::count() const {
|
size_t LicenseIndex::count() const {
|
||||||
@@ -288,3 +248,56 @@ shared_ptr<License> LicenseIndex::verify_bb(const string& username, const string
|
|||||||
throw missing_license();
|
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;
|
class LicenseIndex;
|
||||||
|
|
||||||
struct License {
|
class License {
|
||||||
|
public:
|
||||||
enum Flag : uint32_t {
|
enum Flag : uint32_t {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
KICK_USER = 0x00000001,
|
KICK_USER = 0x00000001,
|
||||||
@@ -53,14 +54,25 @@ struct License {
|
|||||||
|
|
||||||
License() = default;
|
License() = default;
|
||||||
explicit License(const JSON& json);
|
explicit License(const JSON& json);
|
||||||
|
virtual ~License() = default;
|
||||||
|
|
||||||
JSON json() const;
|
JSON json() const;
|
||||||
void save() const;
|
virtual void save() const;
|
||||||
void delete_file() const;
|
virtual void delete_file() const;
|
||||||
|
|
||||||
std::string str() 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 {
|
class LicenseIndex {
|
||||||
public:
|
public:
|
||||||
class no_username : public std::invalid_argument {
|
class no_username : public std::invalid_argument {
|
||||||
@@ -80,8 +92,10 @@ public:
|
|||||||
missing_license() : invalid_argument("missing license") {}
|
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;
|
size_t count() const;
|
||||||
std::shared_ptr<License> get(uint32_t serial_number) 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<std::string, std::shared_ptr<License>> xb_gamertag_to_license;
|
||||||
std::unordered_map<uint32_t, std::shared_ptr<License>> serial_number_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) {
|
if (!s->allow_unregistered_users) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||||
l->bb_username = cmd.username.decode();
|
l->bb_username = cmd.username.decode();
|
||||||
l->bb_password = cmd.password.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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
l->gc_password = cmd.password.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");
|
send_message_box(c, "Incorrect serial number");
|
||||||
c->should_disconnect = true;
|
c->should_disconnect = true;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
s->license_index->add(l);
|
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");
|
send_message_box(c, "Incorrect serial number");
|
||||||
c->should_disconnect = true;
|
c->should_disconnect = true;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
s->license_index->add(l);
|
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);
|
send_command(c, 0x90, 0x03);
|
||||||
c->should_disconnect = true;
|
c->should_disconnect = true;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
s->license_index->add(l);
|
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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
s->license_index->add(l);
|
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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else if (is_v1_or_v2(c->version())) {
|
} 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->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
s->license_index->add(l);
|
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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = serial_number;
|
l->serial_number = serial_number;
|
||||||
l->access_key = cmd.access_key.decode();
|
l->access_key = cmd.access_key.decode();
|
||||||
if (is_gc(c->version())) {
|
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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else if (is_v1_or_v2(c->version())) {
|
} 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->serial_number = serial_number;
|
||||||
l->access_key = base_cmd->access_key.decode();
|
l->access_key = base_cmd->access_key.decode();
|
||||||
s->license_index->add(l);
|
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;
|
return;
|
||||||
|
|
||||||
} catch (const LicenseIndex::missing_license& e) {
|
} 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->serial_number = fnv1a32(xb_gamertag) & 0x7FFFFFFF;
|
||||||
l->xb_gamertag = xb_gamertag;
|
l->xb_gamertag = xb_gamertag;
|
||||||
l->xb_user_id = xb_user_id;
|
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;
|
c->should_disconnect = true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||||
l->bb_username = cmd.username.decode();
|
l->bb_username = cmd.username.decode();
|
||||||
l->bb_password = cmd.password.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;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
auto l = make_shared<License>();
|
auto l = s->license_index->create_license();
|
||||||
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
l->serial_number = fnv1a32(cmd.username.decode()) & 0x7FFFFFFF;
|
||||||
l->bb_username = cmd.username.decode();
|
l->bb_username = cmd.username.decode();
|
||||||
l->bb_password = cmd.password.decode();
|
l->bb_password = cmd.password.decode();
|
||||||
|
|||||||
+3
-2
@@ -321,7 +321,7 @@ Proxy session commands:\n\
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (command_name == "add-license") {
|
} 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, ' ')) {
|
for (const string& token : split(command_args, ' ')) {
|
||||||
if (starts_with(token, "bb-username=")) {
|
if (starts_with(token, "bb-username=")) {
|
||||||
@@ -376,7 +376,8 @@ Proxy session commands:\n\
|
|||||||
uint32_t serial_number = stoul(tokens[0]);
|
uint32_t serial_number = stoul(tokens[0]);
|
||||||
tokens.erase(tokens.begin());
|
tokens.erase(tokens.begin());
|
||||||
auto orig_l = this->state->license_index->get(serial_number);
|
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);
|
this->state->license_index->remove(orig_l->serial_number);
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -973,7 +973,7 @@ void ServerState::load_bb_private_keys() {
|
|||||||
|
|
||||||
void ServerState::load_licenses() {
|
void ServerState::load_licenses() {
|
||||||
config_log.info("Indexing 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() {
|
void ServerState::load_teams() {
|
||||||
|
|||||||
Reference in New Issue
Block a user