use std::strings in places of c-strings in most places

This commit is contained in:
Martin Michelsen
2022-04-03 23:31:24 -07:00
parent 1d70933c17
commit 06fd71f7a6
19 changed files with 191 additions and 188 deletions
+63 -67
View File
@@ -322,15 +322,15 @@ uint8_t npc_for_name(const u16string& name) {
class precondition_failed { class precondition_failed {
public: public:
precondition_failed(const char16_t* user_msg) : user_msg(user_msg) { } precondition_failed(const std::u16string& user_msg) : user_msg(user_msg) { }
~precondition_failed() = default; ~precondition_failed() = default;
const char16_t* what() const { const std::u16string& what() const {
return this->user_msg; return this->user_msg;
} }
private: private:
const char16_t* user_msg; std::u16string user_msg;
}; };
static void check_privileges(shared_ptr<Client> c, uint64_t mask) { static void check_privileges(shared_ptr<Client> c, uint64_t mask) {
@@ -388,7 +388,7 @@ static void check_is_leader(shared_ptr<Lobby> l, shared_ptr<Client> c) {
// Message commands // Message commands
static void command_lobby_info(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_lobby_info(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
// no preconditions - everyone can use this command // no preconditions - everyone can use this command
if (!l) { if (!l) {
@@ -417,20 +417,20 @@ static void command_lobby_info(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_ax(shared_ptr<ServerState>, shared_ptr<Lobby>, static void command_ax(shared_ptr<ServerState>, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::ANNOUNCE); check_privileges(c, Privilege::ANNOUNCE);
string message = encode_sjis(args); string message = encode_sjis(args);
log(INFO, "[Client message from %010u] %s\n", c->license->serial_number, message.c_str()); log(INFO, "[Client message from %010u] %s\n", c->license->serial_number, message.c_str());
} }
static void command_announce(shared_ptr<ServerState> s, shared_ptr<Lobby>, static void command_announce(shared_ptr<ServerState> s, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::ANNOUNCE); check_privileges(c, Privilege::ANNOUNCE);
send_text_message(s, args); send_text_message(s, args);
} }
static void command_arrow(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_arrow(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
// no preconditions // no preconditions
c->lobby_arrow_color = stoull(encode_sjis(args), nullptr, 0); c->lobby_arrow_color = stoull(encode_sjis(args), nullptr, 0);
if (!l->is_game()) { if (!l->is_game()) {
@@ -442,7 +442,7 @@ static void command_arrow(shared_ptr<ServerState>, shared_ptr<Lobby> l,
// Lobby commands // Lobby commands
static void command_cheat(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_cheat(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
check_is_game(l, true); check_is_game(l, true);
check_is_leader(l, c); check_is_leader(l, c);
@@ -466,7 +466,7 @@ static void command_cheat(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_lobby_event(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_lobby_event(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, false); check_is_game(l, false);
check_privileges(c, Privilege::CHANGE_EVENT); check_privileges(c, Privilege::CHANGE_EVENT);
@@ -481,7 +481,7 @@ static void command_lobby_event(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_lobby_event_all(shared_ptr<ServerState> s, shared_ptr<Lobby>, static void command_lobby_event_all(shared_ptr<ServerState> s, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::CHANGE_EVENT); check_privileges(c, Privilege::CHANGE_EVENT);
uint8_t new_event = event_for_name(args); uint8_t new_event = event_for_name(args);
@@ -501,7 +501,7 @@ static void command_lobby_event_all(shared_ptr<ServerState> s, shared_ptr<Lobby>
} }
static void command_lobby_type(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_lobby_type(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, false); check_is_game(l, false);
check_privileges(c, Privilege::CHANGE_EVENT); check_privileges(c, Privilege::CHANGE_EVENT);
@@ -527,7 +527,7 @@ static void command_lobby_type(shared_ptr<ServerState>, shared_ptr<Lobby> l,
// Game commands // Game commands
static void command_secid(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_secid(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, false); check_is_game(l, false);
if (!args[0]) { if (!args[0]) {
@@ -540,7 +540,7 @@ static void command_secid(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_password(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_password(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true); check_is_game(l, true);
check_is_leader(l, c); check_is_leader(l, c);
@@ -557,7 +557,7 @@ static void command_password(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_min_level(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_min_level(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true); check_is_game(l, true);
check_is_leader(l, c); check_is_leader(l, c);
@@ -568,7 +568,7 @@ static void command_min_level(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_max_level(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_max_level(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true); check_is_game(l, true);
check_is_leader(l, c); check_is_leader(l, c);
@@ -588,7 +588,7 @@ static void command_max_level(shared_ptr<ServerState>, shared_ptr<Lobby> l,
// Character commands // Character commands
static void command_edit(shared_ptr<ServerState> s, shared_ptr<Lobby> l, static void command_edit(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, false); check_is_game(l, false);
check_version(c, GameVersion::BB); check_version(c, GameVersion::BB);
@@ -673,7 +673,7 @@ static void command_edit(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
} }
static void command_change_bank(shared_ptr<ServerState>, shared_ptr<Lobby>, static void command_change_bank(shared_ptr<ServerState>, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
check_version(c, GameVersion::BB); check_version(c, GameVersion::BB);
// TODO: implement this // TODO: implement this
@@ -681,7 +681,7 @@ static void command_change_bank(shared_ptr<ServerState>, shared_ptr<Lobby>,
} }
static void command_convert_char_to_bb(shared_ptr<ServerState> s, static void command_convert_char_to_bb(shared_ptr<ServerState> s,
shared_ptr<Lobby> l, shared_ptr<Client> c, const char16_t* args) { shared_ptr<Lobby> l, shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, false); check_is_game(l, false);
check_not_version(c, GameVersion::BB); check_not_version(c, GameVersion::BB);
@@ -716,10 +716,10 @@ static void command_convert_char_to_bb(shared_ptr<ServerState> s,
// Administration commands // Administration commands
static void command_silence(shared_ptr<ServerState> s, shared_ptr<Lobby> l, static void command_silence(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::SILENCE_USER); check_privileges(c, Privilege::SILENCE_USER);
auto target = s->find_client(args); auto target = s->find_client(&args);
if (!target->license) { if (!target->license) {
// this should be impossible, but I'll bet it's not actually // this should be impossible, but I'll bet it's not actually
send_text_message(c, u"$C6Client not logged in"); send_text_message(c, u"$C6Client not logged in");
@@ -738,12 +738,12 @@ static void command_silence(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
} }
static void command_kick(shared_ptr<ServerState> s, shared_ptr<Lobby> l, static void command_kick(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::KICK_USER); check_privileges(c, Privilege::KICK_USER);
auto target = s->find_client(args); auto target = s->find_client(&args);
if (!target->license) { if (!target->license) {
// this should be impossible, but I'll bet it's not actually // This should be impossible, but I'll bet it's not actually
send_text_message(c, u"$C6Client not logged in"); send_text_message(c, u"$C6Client not logged in");
return; return;
} }
@@ -760,7 +760,7 @@ static void command_kick(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
} }
static void command_ban(shared_ptr<ServerState> s, shared_ptr<Lobby> l, static void command_ban(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_privileges(c, Privilege::BAN_USER); check_privileges(c, Privilege::BAN_USER);
u16string args_str(args); u16string args_str(args);
@@ -770,9 +770,10 @@ static void command_ban(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
return; return;
} }
auto target = s->find_client(args_str.data() + space_pos + 1); u16string identifier = args_str.substr(space_pos + 1);
auto target = s->find_client(&identifier);
if (!target->license) { if (!target->license) {
// this should be impossible, but I'll bet it's not actually // This should be impossible, but I'll bet it's not actually
send_text_message(c, u"$C6Client not logged in"); send_text_message(c, u"$C6Client not logged in");
return; return;
} }
@@ -813,7 +814,7 @@ static void command_ban(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
// Cheat commands // Cheat commands
static void command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true); check_is_game(l, true);
check_cheats_enabled(l); check_cheats_enabled(l);
@@ -842,7 +843,7 @@ static void command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_song(shared_ptr<ServerState>, shared_ptr<Lobby>, static void command_song(shared_ptr<ServerState>, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_ep3(c, true); check_is_ep3(c, true);
uint32_t song = stoul(encode_sjis(args), nullptr, 0); uint32_t song = stoul(encode_sjis(args), nullptr, 0);
@@ -850,7 +851,7 @@ static void command_song(shared_ptr<ServerState>, shared_ptr<Lobby>,
} }
static void command_infinite_hp(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_infinite_hp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
check_is_game(l, true); check_is_game(l, true);
check_cheats_enabled(l); check_cheats_enabled(l);
@@ -859,7 +860,7 @@ static void command_infinite_hp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_infinite_tp(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_infinite_tp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
check_is_game(l, true); check_is_game(l, true);
check_cheats_enabled(l); check_cheats_enabled(l);
@@ -868,7 +869,7 @@ static void command_infinite_tp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_switch_assist(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_switch_assist(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) { shared_ptr<Client> c, const std::u16string&) {
check_is_game(l, true); check_is_game(l, true);
check_cheats_enabled(l); check_cheats_enabled(l);
@@ -877,7 +878,7 @@ static void command_switch_assist(shared_ptr<ServerState>, shared_ptr<Lobby> l,
} }
static void command_item(shared_ptr<ServerState>, shared_ptr<Lobby> l, static void command_item(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args) { shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true); check_is_game(l, true);
check_cheats_enabled(l); check_cheats_enabled(l);
@@ -908,50 +909,45 @@ static void command_item(shared_ptr<ServerState>, shared_ptr<Lobby> l,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef void (*handler_t)(shared_ptr<ServerState> s, shared_ptr<Lobby> l, typedef void (*handler_t)(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t* args); shared_ptr<Client> c, const std::u16string& args);
struct ChatCommandDefinition { struct ChatCommandDefinition {
handler_t handler; handler_t handler;
const char16_t* usage; u16string usage;
}; };
static const unordered_map<u16string, ChatCommandDefinition> chat_commands({ static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
// TODO: implement command_help and actually use the usage strings here // TODO: implement command_help and actually use the usage strings here
{u"allevent" , {command_lobby_event_all , u"Usage:\nallevent <name/ID>"}}, {u"$allevent" , {command_lobby_event_all , u"Usage:\nallevent <name/ID>"}},
{u"ann" , {command_announce , u"Usage:\nann <message>"}}, {u"$ann" , {command_announce , u"Usage:\nann <message>"}},
{u"arrow" , {command_arrow , u"Usage:\narrow <color>"}}, {u"$arrow" , {command_arrow , u"Usage:\narrow <color>"}},
{u"ax" , {command_ax , u"Usage:\nax <message>"}}, {u"$ax" , {command_ax , u"Usage:\nax <message>"}},
{u"ban" , {command_ban , u"Usage:\nban <name-or-number>"}}, {u"$ban" , {command_ban , u"Usage:\nban <name-or-number>"}},
{u"bbchar" , {command_convert_char_to_bb, u"Usage:\nbbchar <user> <pass> <1-4>"}}, {u"$bbchar" , {command_convert_char_to_bb, u"Usage:\nbbchar <user> <pass> <1-4>"}},
{u"changebank", {command_change_bank , u"Usage:\nchangebank <bank name>"}}, {u"$changebank", {command_change_bank , u"Usage:\nchangebank <bank name>"}},
{u"cheat" , {command_cheat , u"Usage:\ncheat"}}, {u"$cheat" , {command_cheat , u"Usage:\ncheat"}},
{u"edit" , {command_edit , u"Usage:\nedit <stat> <value>"}}, {u"$edit" , {command_edit , u"Usage:\nedit <stat> <value>"}},
{u"event" , {command_lobby_event , u"Usage:\nevent <name>"}}, {u"$event" , {command_lobby_event , u"Usage:\nevent <name>"}},
{u"infhp" , {command_infinite_hp , u"Usage:\ninfhp"}}, {u"$infhp" , {command_infinite_hp , u"Usage:\ninfhp"}},
{u"inftp" , {command_infinite_tp , u"Usage:\ninftp"}}, {u"$inftp" , {command_infinite_tp , u"Usage:\ninftp"}},
{u"item" , {command_item , u"Usage:\nitem <item-code>"}}, {u"$item" , {command_item , u"Usage:\nitem <item-code>"}},
{u"kick" , {command_kick , u"Usage:\nkick <name-or-number>"}}, {u"$kick" , {command_kick , u"Usage:\nkick <name-or-number>"}},
{u"li" , {command_lobby_info , u"Usage:\nli"}}, {u"$li" , {command_lobby_info , u"Usage:\nli"}},
{u"maxlevel" , {command_max_level , u"Usage:\nmax_level <level>"}}, {u"$maxlevel" , {command_max_level , u"Usage:\nmax_level <level>"}},
{u"minlevel" , {command_min_level , u"Usage:\nmin_level <level>"}}, {u"$minlevel" , {command_min_level , u"Usage:\nmin_level <level>"}},
{u"password" , {command_password , u"Usage:\nlock [password]\nomit password to\nunlock game"}}, {u"$password" , {command_password , u"Usage:\nlock [password]\nomit password to\nunlock game"}},
{u"secid" , {command_secid , u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}}, {u"$secid" , {command_secid , u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}},
{u"silence" , {command_silence , u"Usage:\nsilence <name-or-number>"}}, {u"$silence" , {command_silence , u"Usage:\nsilence <name-or-number>"}},
{u"song" , {command_song , u"Usage:\nsong <song-number>"}}, {u"$song" , {command_song , u"Usage:\nsong <song-number>"}},
{u"swa" , {command_switch_assist , u"Usage:\nswa"}}, {u"$swa" , {command_switch_assist , u"Usage:\nswa"}},
{u"type" , {command_lobby_type , u"Usage:\ntype <name>"}}, {u"$type" , {command_lobby_type , u"Usage:\ntype <name>"}},
{u"warp" , {command_warp , u"Usage:\nwarp <area-number>"}}, {u"$warp" , {command_warp , u"Usage:\nwarp <area-number>"}},
}); });
// this function is called every time any player sends a chat beginning with a dollar sign. // This function is called every time any player sends a chat beginning with a
// It is this function's responsibility to see if the chat is a command, and to // dollar sign. It is this function's responsibility to see if the chat is a
// execute the command and block the chat if it is. // command, and to execute the command and block the chat if it is.
void process_chat_command(std::shared_ptr<ServerState> s, std::shared_ptr<Lobby> l, void process_chat_command(std::shared_ptr<ServerState> s, std::shared_ptr<Lobby> l,
std::shared_ptr<Client> c, const char16_t* text) { std::shared_ptr<Client> c, const std::u16string& text) {
// remove the chat command marker
if (text[0] == u'$') {
text++;
}
u16string command_name; u16string command_name;
u16string text_str(text); u16string text_str(text);
+1 -1
View File
@@ -35,4 +35,4 @@ uint8_t npc_for_name(const std::string& name);
uint8_t npc_for_name(const std::u16string& name); uint8_t npc_for_name(const std::u16string& name);
void process_chat_command(std::shared_ptr<ServerState> s, std::shared_ptr<Lobby> l, void process_chat_command(std::shared_ptr<ServerState> s, std::shared_ptr<Lobby> l,
std::shared_ptr<Client> c, const char16_t* text); std::shared_ptr<Client> c, const std::u16string& text);
+1 -1
View File
@@ -10,7 +10,7 @@ using namespace std;
LevelTable::LevelTable(const char* filename, bool compressed) { LevelTable::LevelTable(const string& filename, bool compressed) {
string data = load_file(filename); string data = load_file(filename);
if (compressed) { if (compressed) {
+1 -1
View File
@@ -24,7 +24,7 @@ struct LevelTable {
uint32_t unknown[12]; uint32_t unknown[12];
LevelStats levels[12][200]; LevelStats levels[12][200];
LevelTable(const char* filename, bool compressed); LevelTable(const std::string& filename, bool compressed);
const PlayerStats& base_stats_for_class(uint8_t char_class) const; const PlayerStats& base_stats_for_class(uint8_t char_class) const;
const LevelStats& stats_for_level(uint8_t char_class, uint8_t level) const; const LevelStats& stats_for_level(uint8_t char_class, uint8_t level) const;
+26 -21
View File
@@ -73,14 +73,11 @@ void LicenseManager::save() const {
} }
shared_ptr<const License> LicenseManager::verify_pc(uint32_t serial_number, shared_ptr<const License> LicenseManager::verify_pc(uint32_t serial_number,
const char* access_key, const char* password) const { const string& access_key) const {
auto& license = this->serial_number_to_license.at(serial_number); auto& license = this->serial_number_to_license.at(serial_number);
if (!license->access_key.eq_n(access_key, 8)) { if (!license->access_key.eq_n(access_key, 8)) {
throw invalid_argument("incorrect access key"); throw invalid_argument("incorrect access key");
} }
if (password && (license->gc_password != password)) {
throw invalid_argument("incorrect password");
}
if (license->ban_end_time && (license->ban_end_time >= now())) { if (license->ban_end_time && (license->ban_end_time >= now())) {
throw invalid_argument("user is banned"); throw invalid_argument("user is banned");
@@ -89,25 +86,36 @@ shared_ptr<const License> LicenseManager::verify_pc(uint32_t serial_number,
} }
shared_ptr<const License> LicenseManager::verify_gc(uint32_t serial_number, shared_ptr<const License> LicenseManager::verify_gc(uint32_t serial_number,
const char* access_key, const char* password) const { const string& access_key) const {
auto& license = this->serial_number_to_license.at(serial_number); auto& license = this->serial_number_to_license.at(serial_number);
if (!license->access_key.eq_n(access_key, 12)) { if (!license->access_key.eq_n(access_key, 12)) {
throw invalid_argument("incorrect access key"); throw invalid_argument("incorrect access key");
} }
if (password && (license->gc_password != password)) {
throw invalid_argument("incorrect password");
}
if (license->ban_end_time && (license->ban_end_time >= now())) { if (license->ban_end_time && (license->ban_end_time >= now())) {
throw invalid_argument("user is banned"); throw invalid_argument("user is banned");
} }
return license; return license;
} }
shared_ptr<const License> LicenseManager::verify_bb(const char* username, shared_ptr<const License> LicenseManager::verify_gc(uint32_t serial_number,
const char* password) const { const string& access_key, const string& password) const {
auto& license = this->serial_number_to_license.at(serial_number);
if (!license->access_key.eq_n(access_key, 12)) {
throw invalid_argument("incorrect access key");
}
if (license->gc_password != password) {
throw invalid_argument("incorrect password");
}
if (license->ban_end_time && (license->ban_end_time >= now())) {
throw invalid_argument("user is banned");
}
return license;
}
shared_ptr<const License> LicenseManager::verify_bb(const string& username,
const string& password) const {
auto& license = this->bb_username_to_license.at(username); auto& license = this->bb_username_to_license.at(username);
if (password && (license->bb_password != password)) { if (license->bb_password != password) {
throw invalid_argument("incorrect password"); throw invalid_argument("incorrect password");
} }
@@ -155,13 +163,10 @@ vector<License> LicenseManager::snapshot() const {
shared_ptr<License> LicenseManager::create_license_pc( shared_ptr<License> LicenseManager::create_license_pc(
uint32_t serial_number,const char* access_key, const char* password, bool temporary) { uint32_t serial_number, const string& access_key, bool temporary) {
shared_ptr<License> l(new License()); shared_ptr<License> l(new License());
l->serial_number = serial_number; l->serial_number = serial_number;
l->access_key = access_key; l->access_key = access_key;
if (password) {
l->gc_password = password;
}
if (temporary) { if (temporary) {
l->privileges |= Privilege::TEMPORARY; l->privileges |= Privilege::TEMPORARY;
} }
@@ -169,13 +174,12 @@ shared_ptr<License> LicenseManager::create_license_pc(
} }
shared_ptr<License> LicenseManager::create_license_gc( shared_ptr<License> LicenseManager::create_license_gc(
uint32_t serial_number, const char* access_key, const char* password, bool temporary) { uint32_t serial_number, const string& access_key, const string& password,
bool temporary) {
shared_ptr<License> l(new License()); shared_ptr<License> l(new License());
l->serial_number = serial_number; l->serial_number = serial_number;
l->access_key = access_key; l->access_key = access_key;
if (password) { l->gc_password = password;
l->gc_password = password;
}
if (temporary) { if (temporary) {
l->privileges |= Privilege::TEMPORARY; l->privileges |= Privilege::TEMPORARY;
} }
@@ -183,7 +187,8 @@ shared_ptr<License> LicenseManager::create_license_gc(
} }
shared_ptr<License> LicenseManager::create_license_bb( shared_ptr<License> LicenseManager::create_license_bb(
uint32_t serial_number, const char* username, const char* password, bool temporary) { uint32_t serial_number, const string& username, const string& password,
bool temporary) {
shared_ptr<License> l(new License()); shared_ptr<License> l(new License());
l->serial_number = serial_number; l->serial_number = serial_number;
l->username = username; l->username = username;
+11 -7
View File
@@ -50,11 +50,13 @@ public:
~LicenseManager() = default; ~LicenseManager() = default;
std::shared_ptr<const License> verify_pc(uint32_t serial_number, std::shared_ptr<const License> verify_pc(uint32_t serial_number,
const char* access_key, const char* password) const; const std::string& access_key) const;
std::shared_ptr<const License> verify_gc(uint32_t serial_number, std::shared_ptr<const License> verify_gc(uint32_t serial_number,
const char* access_key, const char* password) const; const std::string& access_key) const;
std::shared_ptr<const License> verify_bb(const char* username, std::shared_ptr<const License> verify_gc(uint32_t serial_number,
const char* password) const; const std::string& access_key, const std::string& password) const;
std::shared_ptr<const License> verify_bb(const std::string& username,
const std::string& password) const;
void ban_until(uint32_t serial_number, uint64_t seconds); void ban_until(uint32_t serial_number, uint64_t seconds);
size_t count() const; size_t count() const;
@@ -64,11 +66,13 @@ public:
std::vector<License> snapshot() const; std::vector<License> snapshot() const;
static std::shared_ptr<License> create_license_pc( static std::shared_ptr<License> create_license_pc(
uint32_t serial_number, const char* access_key, const char* password, bool temporary); uint32_t serial_number, const std::string& access_key, bool temporary);
static std::shared_ptr<License> create_license_gc( static std::shared_ptr<License> create_license_gc(
uint32_t serial_number, const char* access_key, const char* password, bool temporary); uint32_t serial_number, const std::string& access_key,
const std::string& password, bool temporary);
static std::shared_ptr<License> create_license_bb( static std::shared_ptr<License> create_license_bb(
uint32_t serial_number, const char* username, const char* password, bool temporary); uint32_t serial_number, const std::string& username,
const std::string& password, bool temporary);
protected: protected:
void save() const; void save() const;
+2 -2
View File
@@ -135,7 +135,7 @@ void Lobby::move_client_to_lobby(shared_ptr<Lobby> dest_lobby,
shared_ptr<Client> Lobby::find_client(const char16_t* identifier, shared_ptr<Client> Lobby::find_client(const u16string* identifier,
uint64_t serial_number) { uint64_t serial_number) {
for (size_t x = 0; x < this->max_clients; x++) { for (size_t x = 0; x < this->max_clients; x++) {
if (!this->clients[x]) { if (!this->clients[x]) {
@@ -145,7 +145,7 @@ shared_ptr<Client> Lobby::find_client(const char16_t* identifier,
(this->clients[x]->license->serial_number == serial_number)) { (this->clients[x]->license->serial_number == serial_number)) {
return this->clients[x]; return this->clients[x];
} }
if (identifier && (this->clients[x]->player.disp.name == identifier)) { if (identifier && (this->clients[x]->player.disp.name == *identifier)) {
return this->clients[x]; return this->clients[x];
} }
} }
+2 -1
View File
@@ -73,7 +73,8 @@ struct Lobby {
void move_client_to_lobby(std::shared_ptr<Lobby> dest_lobby, void move_client_to_lobby(std::shared_ptr<Lobby> dest_lobby,
std::shared_ptr<Client> c); std::shared_ptr<Client> c);
std::shared_ptr<Client> find_client(const char16_t* identifier = nullptr, std::shared_ptr<Client> find_client(
const std::u16string* identifier = nullptr,
uint64_t serial_number = 0); uint64_t serial_number = 0);
void add_item(const PlayerInventoryItem& item); void add_item(const PlayerInventoryItem& item);
+1 -1
View File
@@ -433,7 +433,7 @@ static vector<PSOEnemy> parse_map(uint8_t episode, uint8_t difficulty,
return enemies; return enemies;
} }
vector<PSOEnemy> load_map(const char* filename, uint8_t episode, vector<PSOEnemy> load_map(const std::string& filename, uint8_t episode,
uint8_t difficulty, const BattleParams* battle_params, bool alt_enemies) { uint8_t difficulty, const BattleParams* battle_params, bool alt_enemies) {
shared_ptr<const string> data = file_cache.get(filename); shared_ptr<const string> data = file_cache.get(filename);
const EnemyEntry* entries = reinterpret_cast<const EnemyEntry*>(data->data()); const EnemyEntry* entries = reinterpret_cast<const EnemyEntry*>(data->data());
+1 -1
View File
@@ -48,5 +48,5 @@ struct PSOEnemy {
PSOEnemy(uint32_t experience, uint32_t rt_index); PSOEnemy(uint32_t experience, uint32_t rt_index);
} __attribute__((packed)); } __attribute__((packed));
std::vector<PSOEnemy> load_map(const char* filename, uint8_t episode, std::vector<PSOEnemy> load_map(const std::string& filename, uint8_t episode,
uint8_t difficulty, const BattleParams* bp, bool alt_enemies); uint8_t difficulty, const BattleParams* bp, bool alt_enemies);
+2 -1
View File
@@ -71,7 +71,8 @@ struct PlayerBank {
void load(const std::string& filename); void load(const std::string& filename);
void save(const std::string& filename) const; void save(const std::string& filename) const;
bool switch_with_file(const char* save_filename, const char* load_filename); bool switch_with_file(const std::string& save_filename,
const std::string& load_filename);
void add_item(const PlayerBankItem& item); void add_item(const PlayerBankItem& item);
void remove_item(uint32_t item_id, uint32_t amount, PlayerBankItem* item); void remove_item(uint32_t item_id, uint32_t amount, PlayerBankItem* item);
+2 -4
View File
@@ -251,9 +251,8 @@ void ProxyServer::UnlinkedSession::on_client_input() {
throw runtime_error("command is not 9D"); throw runtime_error("command is not 9D");
} }
const auto& cmd = check_size_t<C_Login_PC_9D>(data, sizeof(C_Login_PC_9D), sizeof(C_LoginWithUnusedSpace_PC_9D)); const auto& cmd = check_size_t<C_Login_PC_9D>(data, sizeof(C_Login_PC_9D), sizeof(C_LoginWithUnusedSpace_PC_9D));
uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16);
license = this->server->state->license_manager->verify_pc( license = this->server->state->license_manager->verify_pc(
serial_number, cmd.access_key.c_str(), nullptr); stoul(cmd.serial_number, nullptr, 16), cmd.access_key);
sub_version = cmd.sub_version; sub_version = cmd.sub_version;
character_name = cmd.name; character_name = cmd.name;
@@ -264,9 +263,8 @@ void ProxyServer::UnlinkedSession::on_client_input() {
throw runtime_error("command is not 9E"); throw runtime_error("command is not 9E");
} }
const auto& cmd = check_size_t<C_Login_GC_9E>(data, sizeof(C_Login_GC_9E), sizeof(C_LoginWithUnusedSpace_GC_9E)); const auto& cmd = check_size_t<C_Login_GC_9E>(data, sizeof(C_Login_GC_9E), sizeof(C_LoginWithUnusedSpace_GC_9E));
uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16);
license = this->server->state->license_manager->verify_gc( license = this->server->state->license_manager->verify_gc(
serial_number, cmd.access_key.c_str(), nullptr); stoul(cmd.serial_number, nullptr, 16), cmd.access_key);
sub_version = cmd.sub_version; sub_version = cmd.sub_version;
character_name = cmd.name; character_name = cmd.name;
client_config = cmd.client_config.cfg; client_config = cmd.client_config.cfg;
+1 -1
View File
@@ -402,7 +402,7 @@ string Quest::decode_gci(const string& filename) {
QuestIndex::QuestIndex(const char* directory) : directory(directory) { QuestIndex::QuestIndex(const std::string& directory) : directory(directory) {
auto filename_set = list_directory(this->directory); auto filename_set = list_directory(this->directory);
vector<string> filenames(filename_set.begin(), filename_set.end()); vector<string> filenames(filename_set.begin(), filename_set.end());
sort(filenames.begin(), filenames.end()); sort(filenames.begin(), filenames.end());
+1 -1
View File
@@ -80,7 +80,7 @@ struct QuestIndex {
std::map<std::string, std::shared_ptr<std::string>> gba_file_contents; std::map<std::string, std::shared_ptr<std::string>> gba_file_contents;
QuestIndex(const char* directory); QuestIndex(const std::string& directory);
std::shared_ptr<const Quest> get(GameVersion version, uint32_t id) const; std::shared_ptr<const Quest> get(GameVersion version, uint32_t id) const;
std::shared_ptr<const std::string> get_gba(const std::string& name) const; std::shared_ptr<const std::string> get_gba(const std::string& name) const;
+36 -40
View File
@@ -24,6 +24,10 @@ using namespace std;
extern FileContentsCache file_cache;
enum ClientStateBB { enum ClientStateBB {
// initial connection. server will redirect client to another port. // initial connection. server will redirect client to another port.
INITIAL_LOGIN = 0x00, INITIAL_LOGIN = 0x00,
@@ -201,10 +205,10 @@ void process_verify_license_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint16_t, uint32_t, const string& data) { // DB uint16_t, uint32_t, const string& data) { // DB
const auto& cmd = check_size_t<C_VerifyLicense_GC_DB>(data); const auto& cmd = check_size_t<C_VerifyLicense_GC_DB>(data);
uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16); uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try { try {
c->license = s->license_manager->verify_gc(serial_number, c->license = s->license_manager->verify_gc(serial_number, cmd.access_key,
cmd.access_key.c_str(), cmd.password.c_str()); cmd.password);
} catch (const exception& e) { } catch (const exception& e) {
if (!s->allow_unregistered_users) { if (!s->allow_unregistered_users) {
u16string message = u"Login failed: " + decode_sjis(e.what()); u16string message = u"Login failed: " + decode_sjis(e.what());
@@ -212,8 +216,8 @@ void process_verify_license_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
c->should_disconnect = true; c->should_disconnect = true;
return; return;
} else { } else {
auto l = LicenseManager::create_license_gc(serial_number, auto l = LicenseManager::create_license_gc(serial_number, cmd.access_key,
cmd.access_key.c_str(), cmd.password.c_str(), true); cmd.password, true);
s->license_manager->add(l); s->license_manager->add(l);
c->license = l; c->license = l;
} }
@@ -229,14 +233,12 @@ void process_login_a_dc_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
c->flags |= flags_for_version(c->version, cmd.sub_version); c->flags |= flags_for_version(c->version, cmd.sub_version);
uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16); uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try { try {
if (c->version == GameVersion::GC) { if (c->version == GameVersion::GC) {
c->license = s->license_manager->verify_gc(serial_number, c->license = s->license_manager->verify_gc(serial_number, cmd.access_key);
cmd.access_key.c_str(), nullptr);
} else { } else {
c->license = s->license_manager->verify_pc(serial_number, c->license = s->license_manager->verify_pc(serial_number, cmd.access_key);
cmd.access_key.c_str(), nullptr);
} }
} catch (const exception& e) { } catch (const exception& e) {
// On GC, the client should have sent a different command containing the // On GC, the client should have sent a different command containing the
@@ -258,14 +260,13 @@ void process_login_c_dc_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
c->flags |= flags_for_version(c->version, cmd.sub_version); c->flags |= flags_for_version(c->version, cmd.sub_version);
uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16); uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try { try {
if (c->version == GameVersion::GC) { if (c->version == GameVersion::GC) {
c->license = s->license_manager->verify_gc(serial_number, c->license = s->license_manager->verify_gc(serial_number, cmd.access_key,
cmd.access_key.c_str(), cmd.password.c_str()); cmd.password);
} else { } else {
c->license = s->license_manager->verify_pc(serial_number, c->license = s->license_manager->verify_pc(serial_number, cmd.access_key);
cmd.access_key.c_str(), cmd.password.c_str());
} }
} catch (const exception& e) { } catch (const exception& e) {
if (!s->allow_unregistered_users) { if (!s->allow_unregistered_users) {
@@ -276,11 +277,11 @@ void process_login_c_dc_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
} else { } else {
shared_ptr<License> l; shared_ptr<License> l;
if (c->version == GameVersion::GC) { if (c->version == GameVersion::GC) {
l = LicenseManager::create_license_gc(serial_number, l = LicenseManager::create_license_gc(serial_number, cmd.access_key,
cmd.access_key.c_str(), cmd.password.c_str(), true); cmd.password, true);
} else { } else {
l = LicenseManager::create_license_pc(serial_number, l = LicenseManager::create_license_pc(serial_number, cmd.access_key,
cmd.access_key.c_str(), cmd.password.c_str(), true); true);
} }
s->license_manager->add(l); s->license_manager->add(l);
c->license = l; c->license = l;
@@ -322,14 +323,14 @@ void process_login_d_e_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
c->flags |= flags_for_version(c->version, base_cmd->sub_version); c->flags |= flags_for_version(c->version, base_cmd->sub_version);
uint32_t serial_number = strtoul(base_cmd->serial_number.c_str(), nullptr, 16); uint32_t serial_number = stoul(base_cmd->serial_number, nullptr, 16);
try { try {
if (c->version == GameVersion::GC) { if (c->version == GameVersion::GC) {
c->license = s->license_manager->verify_gc(serial_number, c->license = s->license_manager->verify_gc(serial_number,
base_cmd->access_key.c_str(), nullptr); base_cmd->access_key);
} else { } else {
c->license = s->license_manager->verify_pc(serial_number, c->license = s->license_manager->verify_pc(serial_number,
base_cmd->access_key.c_str(), nullptr); base_cmd->access_key);
} }
} catch (const exception& e) { } catch (const exception& e) {
// See comment in 9A handler about why we do this even if unregistered users // See comment in 9A handler about why we do this even if unregistered users
@@ -356,8 +357,7 @@ void process_login_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
c->flags |= flags_for_version(c->version, 0); c->flags |= flags_for_version(c->version, 0);
try { try {
c->license = s->license_manager->verify_bb( c->license = s->license_manager->verify_bb(cmd.username, cmd.password);
cmd.username.c_str(), cmd.password.c_str());
} catch (const exception& e) { } catch (const exception& e) {
u16string message = u"Login failed: " + decode_sjis(e.what()); u16string message = u"Login failed: " + decode_sjis(e.what());
send_message_box(c, message.c_str()); send_message_box(c, message.c_str());
@@ -1150,7 +1150,7 @@ void process_chat_generic(shared_ptr<ServerState> s, shared_ptr<Client> c,
if (processed_text[0] == L'$') { if (processed_text[0] == L'$') {
auto l = s->find_lobby(c->lobby_id); auto l = s->find_lobby(c->lobby_id);
if (l) { if (l) {
process_chat_command(s, l, c, &processed_text[1]); process_chat_command(s, l, c, processed_text);
} }
} else { } else {
if (!c->can_chat) { if (!c->can_chat) {
@@ -1413,13 +1413,12 @@ void process_simple_mail(shared_ptr<ServerState> s, shared_ptr<Client> c,
// If the target has auto-reply enabled, send the autoreply // If the target has auto-reply enabled, send the autoreply
if (!target->player.auto_reply.empty()) { if (!target->player.auto_reply.empty()) {
send_simple_mail(c, target->license->serial_number, send_simple_mail(c, target->license->serial_number,
target->player.disp.name.c_str(), target->player.auto_reply.c_str()); target->player.disp.name, target->player.auto_reply);
} }
// Forward the message // Forward the message
u16string u16message = decode_sjis(cmd.text); u16string msg = decode_sjis(cmd.text);
send_simple_mail(target, c->license->serial_number, send_simple_mail(target, c->license->serial_number, c->player.disp.name, msg);
c->player.disp.name.c_str(), u16message.c_str());
} }
@@ -1469,9 +1468,9 @@ void process_set_blocked_senders_list(shared_ptr<ServerState>, shared_ptr<Client
// Game commands // Game commands
shared_ptr<Lobby> create_game_generic(shared_ptr<ServerState> s, shared_ptr<Lobby> create_game_generic(shared_ptr<ServerState> s,
shared_ptr<Client> c, const char16_t* name, const char16_t* password, shared_ptr<Client> c, const std::u16string& name,
uint8_t episode, uint8_t difficulty, uint8_t battle, uint8_t challenge, const std::u16string& password, uint8_t episode, uint8_t difficulty,
uint8_t solo) { uint8_t battle, uint8_t challenge, uint8_t solo) {
static const uint32_t variation_maxes_online[3][0x20] = { static const uint32_t variation_maxes_online[3][0x20] = {
{1, 1, 1, 5, 1, 5, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, {1, 1, 1, 5, 1, 5, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2,
@@ -1617,7 +1616,7 @@ void process_create_game_pc(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint16_t, uint32_t, const string& data) { // C1 uint16_t, uint32_t, const string& data) { // C1
const auto& cmd = check_size_t<C_CreateGame_PC_C1>(data); const auto& cmd = check_size_t<C_CreateGame_PC_C1>(data);
auto game = create_game_generic(s, c, cmd.name.c_str(), cmd.password.c_str(), 1, auto game = create_game_generic(s, c, cmd.name, cmd.password, 1,
cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, 0); cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, 0);
s->add_lobby(game); s->add_lobby(game);
@@ -1658,9 +1657,8 @@ void process_create_game_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint16_t, uint32_t, const string& data) { // C1 uint16_t, uint32_t, const string& data) { // C1
const auto& cmd = check_size_t<C_CreateGame_BB_C1>(data); const auto& cmd = check_size_t<C_CreateGame_BB_C1>(data);
auto game = create_game_generic(s, c, cmd.name.c_str(), cmd.password.c_str(), auto game = create_game_generic(s, c, cmd.name, cmd.password, cmd.episode,
cmd.episode, cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, cmd.solo_mode);
cmd.solo_mode);
s->add_lobby(game); s->add_lobby(game);
s->change_client_lobby(c, game); s->change_client_lobby(c, game);
@@ -1751,12 +1749,10 @@ independently.\r\n\
message += u"License check "; message += u"License check ";
try { try {
if (c->flags & Client::Flag::BB_PATCH) { if (c->flags & Client::Flag::BB_PATCH) {
c->license = s->license_manager->verify_bb( c->license = s->license_manager->verify_bb(cmd.username, cmd.password);
cmd.username.c_str(), cmd.password.c_str());
} else { } else {
uint32_t serial_number = strtoul(cmd.username.c_str(), nullptr, 16);
c->license = s->license_manager->verify_pc( c->license = s->license_manager->verify_pc(
serial_number, cmd.password.c_str(), nullptr); stoul(cmd.username, nullptr, 16), cmd.password);
} }
message += u"OK"; message += u"OK";
} catch (const exception& e) { } catch (const exception& e) {
+22 -21
View File
@@ -348,7 +348,8 @@ void send_stream_file_bb(shared_ptr<Client> c) {
uint32_t buffer_offset = 0; uint32_t buffer_offset = 0;
for (size_t x = 0; x < entry_count; x++) { for (size_t x = 0; x < entry_count; x++) {
auto filename = string_printf("system/blueburst/%s", entries[x].filename.c_str()); string base_filename = entries[x].filename;
auto filename = "system/blueburst/" + base_filename;
auto file_data = file_cache.get(filename); auto file_data = file_cache.get(filename);
size_t file_data_remaining = file_data->size(); size_t file_data_remaining = file_data->size();
@@ -395,7 +396,7 @@ void send_complete_player_bb(shared_ptr<Client> c) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// patch functions // patch functions
void send_check_directory_patch(shared_ptr<Client> c, const char* dir) { void send_check_directory_patch(shared_ptr<Client> c, const string& dir) {
S_CheckDirectory_Patch_09 cmd = {dir}; S_CheckDirectory_Patch_09 cmd = {dir};
send_command(c, 0x09, 0x00, cmd); send_command(c, 0x09, 0x00, cmd);
} }
@@ -406,12 +407,12 @@ void send_check_directory_patch(shared_ptr<Client> c, const char* dir) {
// message functions // message functions
void send_text(shared_ptr<Client> c, StringWriter& w, uint16_t command, void send_text(shared_ptr<Client> c, StringWriter& w, uint16_t command,
const char16_t* text) { const u16string& text) {
if ((c->version == GameVersion::DC) || (c->version == GameVersion::GC)) { if ((c->version == GameVersion::DC) || (c->version == GameVersion::GC)) {
string data = encode_sjis(text); string data = encode_sjis(text);
add_color(w, data.c_str(), data.size()); add_color(w, data.c_str(), data.size());
} else { } else {
add_color(w, text, text_strlen_t(text)); add_color(w, text.c_str(), text.size());
} }
while (w.str().size() & 3) { while (w.str().size() & 3) {
w.put_u8(0); w.put_u8(0);
@@ -420,44 +421,44 @@ void send_text(shared_ptr<Client> c, StringWriter& w, uint16_t command,
} }
void send_header_text(shared_ptr<Client> c, uint16_t command, void send_header_text(shared_ptr<Client> c, uint16_t command,
uint32_t guild_card_number, const char16_t* text) { uint32_t guild_card_number, const u16string& text) {
StringWriter w; StringWriter w;
w.put(SC_TextHeader_01_06_11_B0({0, guild_card_number})); w.put(SC_TextHeader_01_06_11_B0({0, guild_card_number}));
send_text(c, w, command, text); send_text(c, w, command, text);
} }
void send_text(shared_ptr<Client> c, uint16_t command, void send_text(shared_ptr<Client> c, uint16_t command,
const char16_t* text) { const u16string& text) {
StringWriter w; StringWriter w;
send_text(c, w, command, text); send_text(c, w, command, text);
} }
void send_message_box(shared_ptr<Client> c, const char16_t* text) { void send_message_box(shared_ptr<Client> c, const u16string& text) {
uint16_t command = (c->version == GameVersion::PATCH) ? 0x13 : 0x1A; uint16_t command = (c->version == GameVersion::PATCH) ? 0x13 : 0x1A;
send_text(c, command, text); send_text(c, command, text);
} }
void send_lobby_name(shared_ptr<Client> c, const char16_t* text) { void send_lobby_name(shared_ptr<Client> c, const u16string& text) {
send_text(c, 0x8A, text); send_text(c, 0x8A, text);
} }
void send_quest_info(shared_ptr<Client> c, const char16_t* text) { void send_quest_info(shared_ptr<Client> c, const u16string& text) {
send_text(c, 0xA3, text); send_text(c, 0xA3, text);
} }
void send_lobby_message_box(shared_ptr<Client> c, const char16_t* text) { void send_lobby_message_box(shared_ptr<Client> c, const u16string& text) {
send_header_text(c, 0x01, 0, text); send_header_text(c, 0x01, 0, text);
} }
void send_ship_info(shared_ptr<Client> c, const char16_t* text) { void send_ship_info(shared_ptr<Client> c, const u16string& text) {
send_header_text(c, 0x11, 0, text); send_header_text(c, 0x11, 0, text);
} }
void send_text_message(shared_ptr<Client> c, const char16_t* text) { void send_text_message(shared_ptr<Client> c, const u16string& text) {
send_header_text(c, 0xB0, 0, text); send_header_text(c, 0xB0, 0, text);
} }
void send_text_message(shared_ptr<Lobby> l, const char16_t* text) { void send_text_message(shared_ptr<Lobby> l, const u16string& text) {
for (size_t x = 0; x < l->max_clients; x++) { for (size_t x = 0; x < l->max_clients; x++) {
if (l->clients[x]) { if (l->clients[x]) {
send_text_message(l->clients[x], text); send_text_message(l->clients[x], text);
@@ -465,7 +466,7 @@ void send_text_message(shared_ptr<Lobby> l, const char16_t* text) {
} }
} }
void send_text_message(shared_ptr<ServerState> s, const char16_t* text) { void send_text_message(shared_ptr<ServerState> s, const u16string& text) {
// TODO: We should have a collection of all clients (even those not in any // TODO: We should have a collection of all clients (even those not in any
// lobby) and use that instead here // lobby) and use that instead here
for (auto& l : s->all_lobbies()) { for (auto& l : s->all_lobbies()) {
@@ -474,7 +475,7 @@ void send_text_message(shared_ptr<ServerState> s, const char16_t* text) {
} }
void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number, void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number,
const char16_t* from_name, const char16_t* text) { const u16string& from_name, const u16string& text) {
u16string data; u16string data;
if (c->version == GameVersion::BB) { if (c->version == GameVersion::BB) {
data.append(u"\x09J"); data.append(u"\x09J");
@@ -482,11 +483,11 @@ void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number,
data.append(remove_language_marker(from_name)); data.append(remove_language_marker(from_name));
data.append(u"\x09\x09J"); data.append(u"\x09\x09J");
data.append(text); data.append(text);
send_header_text(c, 0x06, from_guild_card_number, data.c_str()); send_header_text(c, 0x06, from_guild_card_number, data);
} }
void send_simple_mail_gc(std::shared_ptr<Client> c, uint32_t from_guild_card_number, void send_simple_mail_gc(std::shared_ptr<Client> c, uint32_t from_guild_card_number,
const char16_t* from_name, const char16_t* text) { const u16string& from_name, const u16string& text) {
SC_SimpleMail_GC_81 cmd; SC_SimpleMail_GC_81 cmd;
cmd.player_tag = 0x00010000; cmd.player_tag = 0x00010000;
cmd.from_guild_card_number = from_guild_card_number; cmd.from_guild_card_number = from_guild_card_number;
@@ -497,7 +498,7 @@ void send_simple_mail_gc(std::shared_ptr<Client> c, uint32_t from_guild_card_num
} }
void send_simple_mail(std::shared_ptr<Client> c, uint32_t from_guild_card_number, void send_simple_mail(std::shared_ptr<Client> c, uint32_t from_guild_card_number,
const char16_t* from_name, const char16_t* text) { const u16string& from_name, const u16string& text) {
if (c->version == GameVersion::GC) { if (c->version == GameVersion::GC) {
send_simple_mail_gc(c, from_guild_card_number, from_name, text); send_simple_mail_gc(c, from_guild_card_number, from_name, text);
} else { } else {
@@ -652,7 +653,7 @@ void send_guild_card(shared_ptr<Client> c, shared_ptr<Client> source) {
template <typename EntryT> template <typename EntryT>
void send_menu_t( void send_menu_t(
shared_ptr<Client> c, shared_ptr<Client> c,
const char16_t* menu_name, const u16string& menu_name,
uint32_t menu_id, uint32_t menu_id,
const vector<MenuItem>& items, const vector<MenuItem>& items,
bool is_info_menu) { bool is_info_menu) {
@@ -684,7 +685,7 @@ void send_menu_t(
send_command(c, is_info_menu ? 0x1F : 0x07, entries.size() - 1, entries); send_command(c, is_info_menu ? 0x1F : 0x07, entries.size() - 1, entries);
} }
void send_menu(shared_ptr<Client> c, const char16_t* menu_name, void send_menu(shared_ptr<Client> c, const u16string& menu_name,
uint32_t menu_id, const vector<MenuItem>& items, bool is_info_menu) { uint32_t menu_id, const vector<MenuItem>& items, bool is_info_menu) {
if (c->version == GameVersion::PC || c->version == GameVersion::PATCH || if (c->version == GameVersion::PC || c->version == GameVersion::PATCH ||
c->version == GameVersion::BB) { c->version == GameVersion::BB) {
@@ -1306,7 +1307,7 @@ void send_quest_open_file_t(
void send_quest_file_chunk( void send_quest_file_chunk(
shared_ptr<Client> c, shared_ptr<Client> c,
const char* filename, const string& filename,
size_t chunk_index, size_t chunk_index,
const void* data, const void* data,
size_t size, size_t size,
+12 -12
View File
@@ -86,20 +86,20 @@ void send_stream_file_bb(std::shared_ptr<Client> c);
void send_approve_player_choice_bb(std::shared_ptr<Client> c); void send_approve_player_choice_bb(std::shared_ptr<Client> c);
void send_complete_player_bb(std::shared_ptr<Client> c); void send_complete_player_bb(std::shared_ptr<Client> c);
void send_check_directory_patch(std::shared_ptr<Client> c, const char* dir); void send_check_directory_patch(std::shared_ptr<Client> c, const std::string& dir);
void send_message_box(std::shared_ptr<Client> c, const char16_t* text); void send_message_box(std::shared_ptr<Client> c, const std::u16string& text);
void send_lobby_name(std::shared_ptr<Client> c, const char16_t* text); void send_lobby_name(std::shared_ptr<Client> c, const std::u16string& text);
void send_quest_info(std::shared_ptr<Client> c, const char16_t* text); void send_quest_info(std::shared_ptr<Client> c, const std::u16string& text);
void send_lobby_message_box(std::shared_ptr<Client> c, const char16_t* text); void send_lobby_message_box(std::shared_ptr<Client> c, const std::u16string& text);
void send_ship_info(std::shared_ptr<Client> c, const char16_t* text); void send_ship_info(std::shared_ptr<Client> c, const std::u16string& text);
void send_text_message(std::shared_ptr<Client> c, const char16_t* text); void send_text_message(std::shared_ptr<Client> c, const std::u16string& text);
void send_text_message(std::shared_ptr<Lobby> l, const char16_t* text); void send_text_message(std::shared_ptr<Lobby> l, const std::u16string& text);
void send_text_message(std::shared_ptr<ServerState> l, const char16_t* text); void send_text_message(std::shared_ptr<ServerState> l, const std::u16string& text);
void send_chat_message(std::shared_ptr<Client> c, uint32_t from_serial_number, void send_chat_message(std::shared_ptr<Client> c, uint32_t from_serial_number,
const char16_t* from_name, const char16_t* text); const std::u16string& from_name, const std::u16string& text);
void send_simple_mail(std::shared_ptr<Client> c, uint32_t from_serial_number, void send_simple_mail(std::shared_ptr<Client> c, uint32_t from_serial_number,
const char16_t* from_name, const char16_t* text); const std::u16string& from_name, const std::u16string& text);
template <typename TargetT> template <typename TargetT>
__attribute__((format(printf, 2, 3))) void send_text_message_printf( __attribute__((format(printf, 2, 3))) void send_text_message_printf(
@@ -121,7 +121,7 @@ void send_card_search_result(
std::shared_ptr<Lobby> result_lobby); std::shared_ptr<Lobby> result_lobby);
void send_guild_card(std::shared_ptr<Client> c, std::shared_ptr<Client> source); void send_guild_card(std::shared_ptr<Client> c, std::shared_ptr<Client> source);
void send_menu(std::shared_ptr<Client> c, const char16_t* menu_name, void send_menu(std::shared_ptr<Client> c, const std::u16string& menu_name,
uint32_t menu_id, const std::vector<MenuItem>& items, bool is_info_menu); uint32_t menu_id, const std::vector<MenuItem>& items, bool is_info_menu);
void send_game_menu(std::shared_ptr<Client> c, std::shared_ptr<ServerState> s); void send_game_menu(std::shared_ptr<Client> c, std::shared_ptr<ServerState> s);
void send_quest_menu(std::shared_ptr<Client> c, uint32_t menu_id, void send_quest_menu(std::shared_ptr<Client> c, uint32_t menu_id,
+2 -3
View File
@@ -146,13 +146,12 @@ void ServerState::remove_lobby(uint32_t lobby_id) {
this->id_to_lobby.erase(lobby_id); this->id_to_lobby.erase(lobby_id);
} }
shared_ptr<Client> ServerState::find_client(const char16_t* identifier, shared_ptr<Client> ServerState::find_client(const std::u16string* identifier,
uint64_t serial_number, shared_ptr<Lobby> l) { uint64_t serial_number, shared_ptr<Lobby> l) {
if ((serial_number == 0) && identifier) { if ((serial_number == 0) && identifier) {
try { try {
string encoded = encode_sjis(identifier); serial_number = stoull(encode_sjis(*identifier), nullptr, 0);
serial_number = stoull(encoded, nullptr, 0);
} catch (const exception&) { } } catch (const exception&) { }
} }
+4 -2
View File
@@ -94,8 +94,10 @@ struct ServerState {
void add_lobby(std::shared_ptr<Lobby> l); void add_lobby(std::shared_ptr<Lobby> l);
void remove_lobby(uint32_t lobby_id); void remove_lobby(uint32_t lobby_id);
std::shared_ptr<Client> find_client(const char16_t* identifier = nullptr, std::shared_ptr<Client> find_client(
uint64_t serial_number = 0, std::shared_ptr<Lobby> l = nullptr); const std::u16string* identifier = nullptr,
uint64_t serial_number = 0,
std::shared_ptr<Lobby> l = nullptr);
uint32_t connect_address_for_client(std::shared_ptr<Client> c); uint32_t connect_address_for_client(std::shared_ptr<Client> c);