diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 277e03f0..0f10ff37 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -322,15 +322,15 @@ uint8_t npc_for_name(const u16string& name) { class precondition_failed { 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; - const char16_t* what() const { + const std::u16string& what() const { return this->user_msg; } private: - const char16_t* user_msg; + std::u16string user_msg; }; static void check_privileges(shared_ptr c, uint64_t mask) { @@ -388,7 +388,7 @@ static void check_is_leader(shared_ptr l, shared_ptr c) { // Message commands static void command_lobby_info(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { // no preconditions - everyone can use this command if (!l) { @@ -417,20 +417,20 @@ static void command_lobby_info(shared_ptr, shared_ptr l, } static void command_ax(shared_ptr, shared_ptr, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::ANNOUNCE); string message = encode_sjis(args); log(INFO, "[Client message from %010u] %s\n", c->license->serial_number, message.c_str()); } static void command_announce(shared_ptr s, shared_ptr, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::ANNOUNCE); send_text_message(s, args); } static void command_arrow(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { // no preconditions c->lobby_arrow_color = stoull(encode_sjis(args), nullptr, 0); if (!l->is_game()) { @@ -442,7 +442,7 @@ static void command_arrow(shared_ptr, shared_ptr l, // Lobby commands static void command_cheat(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { check_is_game(l, true); check_is_leader(l, c); @@ -466,7 +466,7 @@ static void command_cheat(shared_ptr, shared_ptr l, } static void command_lobby_event(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, false); check_privileges(c, Privilege::CHANGE_EVENT); @@ -481,7 +481,7 @@ static void command_lobby_event(shared_ptr, shared_ptr l, } static void command_lobby_event_all(shared_ptr s, shared_ptr, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::CHANGE_EVENT); uint8_t new_event = event_for_name(args); @@ -501,7 +501,7 @@ static void command_lobby_event_all(shared_ptr s, shared_ptr } static void command_lobby_type(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, false); check_privileges(c, Privilege::CHANGE_EVENT); @@ -527,7 +527,7 @@ static void command_lobby_type(shared_ptr, shared_ptr l, // Game commands static void command_secid(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, false); if (!args[0]) { @@ -540,7 +540,7 @@ static void command_secid(shared_ptr, shared_ptr l, } static void command_password(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, true); check_is_leader(l, c); @@ -557,7 +557,7 @@ static void command_password(shared_ptr, shared_ptr l, } static void command_min_level(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, true); check_is_leader(l, c); @@ -568,7 +568,7 @@ static void command_min_level(shared_ptr, shared_ptr l, } static void command_max_level(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, true); check_is_leader(l, c); @@ -588,7 +588,7 @@ static void command_max_level(shared_ptr, shared_ptr l, // Character commands static void command_edit(shared_ptr s, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, false); check_version(c, GameVersion::BB); @@ -673,7 +673,7 @@ static void command_edit(shared_ptr s, shared_ptr l, } static void command_change_bank(shared_ptr, shared_ptr, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { check_version(c, GameVersion::BB); // TODO: implement this @@ -681,7 +681,7 @@ static void command_change_bank(shared_ptr, shared_ptr, } static void command_convert_char_to_bb(shared_ptr s, - shared_ptr l, shared_ptr c, const char16_t* args) { + shared_ptr l, shared_ptr c, const std::u16string& args) { check_is_game(l, false); check_not_version(c, GameVersion::BB); @@ -716,10 +716,10 @@ static void command_convert_char_to_bb(shared_ptr s, // Administration commands static void command_silence(shared_ptr s, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::SILENCE_USER); - auto target = s->find_client(args); + auto target = s->find_client(&args); if (!target->license) { // this should be impossible, but I'll bet it's not actually send_text_message(c, u"$C6Client not logged in"); @@ -738,12 +738,12 @@ static void command_silence(shared_ptr s, shared_ptr l, } static void command_kick(shared_ptr s, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::KICK_USER); - auto target = s->find_client(args); + auto target = s->find_client(&args); 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"); return; } @@ -760,7 +760,7 @@ static void command_kick(shared_ptr s, shared_ptr l, } static void command_ban(shared_ptr s, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_privileges(c, Privilege::BAN_USER); u16string args_str(args); @@ -770,9 +770,10 @@ static void command_ban(shared_ptr s, shared_ptr l, 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) { - // 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"); return; } @@ -813,7 +814,7 @@ static void command_ban(shared_ptr s, shared_ptr l, // Cheat commands static void command_warp(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, true); check_cheats_enabled(l); @@ -842,7 +843,7 @@ static void command_warp(shared_ptr, shared_ptr l, } static void command_song(shared_ptr, shared_ptr, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_ep3(c, true); uint32_t song = stoul(encode_sjis(args), nullptr, 0); @@ -850,7 +851,7 @@ static void command_song(shared_ptr, shared_ptr, } static void command_infinite_hp(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { check_is_game(l, true); check_cheats_enabled(l); @@ -859,7 +860,7 @@ static void command_infinite_hp(shared_ptr, shared_ptr l, } static void command_infinite_tp(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { check_is_game(l, true); check_cheats_enabled(l); @@ -868,7 +869,7 @@ static void command_infinite_tp(shared_ptr, shared_ptr l, } static void command_switch_assist(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t*) { + shared_ptr c, const std::u16string&) { check_is_game(l, true); check_cheats_enabled(l); @@ -877,7 +878,7 @@ static void command_switch_assist(shared_ptr, shared_ptr l, } static void command_item(shared_ptr, shared_ptr l, - shared_ptr c, const char16_t* args) { + shared_ptr c, const std::u16string& args) { check_is_game(l, true); check_cheats_enabled(l); @@ -908,50 +909,45 @@ static void command_item(shared_ptr, shared_ptr l, //////////////////////////////////////////////////////////////////////////////// typedef void (*handler_t)(shared_ptr s, shared_ptr l, - shared_ptr c, const char16_t* args); + shared_ptr c, const std::u16string& args); struct ChatCommandDefinition { handler_t handler; - const char16_t* usage; + u16string usage; }; static const unordered_map chat_commands({ // TODO: implement command_help and actually use the usage strings here - {u"allevent" , {command_lobby_event_all , u"Usage:\nallevent "}}, - {u"ann" , {command_announce , u"Usage:\nann "}}, - {u"arrow" , {command_arrow , u"Usage:\narrow "}}, - {u"ax" , {command_ax , u"Usage:\nax "}}, - {u"ban" , {command_ban , u"Usage:\nban "}}, - {u"bbchar" , {command_convert_char_to_bb, u"Usage:\nbbchar <1-4>"}}, - {u"changebank", {command_change_bank , u"Usage:\nchangebank "}}, - {u"cheat" , {command_cheat , u"Usage:\ncheat"}}, - {u"edit" , {command_edit , u"Usage:\nedit "}}, - {u"event" , {command_lobby_event , u"Usage:\nevent "}}, - {u"infhp" , {command_infinite_hp , u"Usage:\ninfhp"}}, - {u"inftp" , {command_infinite_tp , u"Usage:\ninftp"}}, - {u"item" , {command_item , u"Usage:\nitem "}}, - {u"kick" , {command_kick , u"Usage:\nkick "}}, - {u"li" , {command_lobby_info , u"Usage:\nli"}}, - {u"maxlevel" , {command_max_level , u"Usage:\nmax_level "}}, - {u"minlevel" , {command_min_level , u"Usage:\nmin_level "}}, - {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"silence" , {command_silence , u"Usage:\nsilence "}}, - {u"song" , {command_song , u"Usage:\nsong "}}, - {u"swa" , {command_switch_assist , u"Usage:\nswa"}}, - {u"type" , {command_lobby_type , u"Usage:\ntype "}}, - {u"warp" , {command_warp , u"Usage:\nwarp "}}, + {u"$allevent" , {command_lobby_event_all , u"Usage:\nallevent "}}, + {u"$ann" , {command_announce , u"Usage:\nann "}}, + {u"$arrow" , {command_arrow , u"Usage:\narrow "}}, + {u"$ax" , {command_ax , u"Usage:\nax "}}, + {u"$ban" , {command_ban , u"Usage:\nban "}}, + {u"$bbchar" , {command_convert_char_to_bb, u"Usage:\nbbchar <1-4>"}}, + {u"$changebank", {command_change_bank , u"Usage:\nchangebank "}}, + {u"$cheat" , {command_cheat , u"Usage:\ncheat"}}, + {u"$edit" , {command_edit , u"Usage:\nedit "}}, + {u"$event" , {command_lobby_event , u"Usage:\nevent "}}, + {u"$infhp" , {command_infinite_hp , u"Usage:\ninfhp"}}, + {u"$inftp" , {command_infinite_tp , u"Usage:\ninftp"}}, + {u"$item" , {command_item , u"Usage:\nitem "}}, + {u"$kick" , {command_kick , u"Usage:\nkick "}}, + {u"$li" , {command_lobby_info , u"Usage:\nli"}}, + {u"$maxlevel" , {command_max_level , u"Usage:\nmax_level "}}, + {u"$minlevel" , {command_min_level , u"Usage:\nmin_level "}}, + {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"$silence" , {command_silence , u"Usage:\nsilence "}}, + {u"$song" , {command_song , u"Usage:\nsong "}}, + {u"$swa" , {command_switch_assist , u"Usage:\nswa"}}, + {u"$type" , {command_lobby_type , u"Usage:\ntype "}}, + {u"$warp" , {command_warp , u"Usage:\nwarp "}}, }); -// this function is called every time any player sends a chat beginning with a dollar sign. -// It is this function's responsibility to see if the chat is a command, and to -// execute the command and block the chat if it is. +// This function is called every time any player sends a chat beginning with a +// dollar sign. It is this function's responsibility to see if the chat is a +// command, and to execute the command and block the chat if it is. void process_chat_command(std::shared_ptr s, std::shared_ptr l, - std::shared_ptr c, const char16_t* text) { - - // remove the chat command marker - if (text[0] == u'$') { - text++; - } + std::shared_ptr c, const std::u16string& text) { u16string command_name; u16string text_str(text); diff --git a/src/ChatCommands.hh b/src/ChatCommands.hh index d197e9d4..db3c80c5 100644 --- a/src/ChatCommands.hh +++ b/src/ChatCommands.hh @@ -35,4 +35,4 @@ uint8_t npc_for_name(const std::string& name); uint8_t npc_for_name(const std::u16string& name); void process_chat_command(std::shared_ptr s, std::shared_ptr l, - std::shared_ptr c, const char16_t* text); + std::shared_ptr c, const std::u16string& text); diff --git a/src/LevelTable.cc b/src/LevelTable.cc index dc0f83c5..70833146 100644 --- a/src/LevelTable.cc +++ b/src/LevelTable.cc @@ -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); if (compressed) { diff --git a/src/LevelTable.hh b/src/LevelTable.hh index bedd1a0a..6f4f8015 100644 --- a/src/LevelTable.hh +++ b/src/LevelTable.hh @@ -24,7 +24,7 @@ struct LevelTable { uint32_t unknown[12]; 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 LevelStats& stats_for_level(uint8_t char_class, uint8_t level) const; diff --git a/src/License.cc b/src/License.cc index 0e7cd368..6a548d9d 100644 --- a/src/License.cc +++ b/src/License.cc @@ -73,14 +73,11 @@ void LicenseManager::save() const { } shared_ptr 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); if (!license->access_key.eq_n(access_key, 8)) { 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())) { throw invalid_argument("user is banned"); @@ -89,25 +86,36 @@ shared_ptr LicenseManager::verify_pc(uint32_t serial_number, } shared_ptr 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); if (!license->access_key.eq_n(access_key, 12)) { 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())) { throw invalid_argument("user is banned"); } return license; } -shared_ptr LicenseManager::verify_bb(const char* username, - const char* password) const { +shared_ptr LicenseManager::verify_gc(uint32_t serial_number, + 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 LicenseManager::verify_bb(const string& username, + const string& password) const { 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"); } @@ -155,13 +163,10 @@ vector LicenseManager::snapshot() const { shared_ptr 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 l(new License()); l->serial_number = serial_number; l->access_key = access_key; - if (password) { - l->gc_password = password; - } if (temporary) { l->privileges |= Privilege::TEMPORARY; } @@ -169,13 +174,12 @@ shared_ptr LicenseManager::create_license_pc( } shared_ptr 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 l(new License()); l->serial_number = serial_number; l->access_key = access_key; - if (password) { - l->gc_password = password; - } + l->gc_password = password; if (temporary) { l->privileges |= Privilege::TEMPORARY; } @@ -183,7 +187,8 @@ shared_ptr LicenseManager::create_license_gc( } shared_ptr 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 l(new License()); l->serial_number = serial_number; l->username = username; diff --git a/src/License.hh b/src/License.hh index 1d3aaf2d..ddc14516 100644 --- a/src/License.hh +++ b/src/License.hh @@ -50,11 +50,13 @@ public: ~LicenseManager() = default; std::shared_ptr verify_pc(uint32_t serial_number, - const char* access_key, const char* password) const; + const std::string& access_key) const; std::shared_ptr verify_gc(uint32_t serial_number, - const char* access_key, const char* password) const; - std::shared_ptr verify_bb(const char* username, - const char* password) const; + const std::string& access_key) const; + std::shared_ptr verify_gc(uint32_t serial_number, + const std::string& access_key, const std::string& password) const; + std::shared_ptr verify_bb(const std::string& username, + const std::string& password) const; void ban_until(uint32_t serial_number, uint64_t seconds); size_t count() const; @@ -64,11 +66,13 @@ public: std::vector snapshot() const; static std::shared_ptr 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 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 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: void save() const; diff --git a/src/Lobby.cc b/src/Lobby.cc index 9c75281a..a6a3186a 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -135,7 +135,7 @@ void Lobby::move_client_to_lobby(shared_ptr dest_lobby, -shared_ptr Lobby::find_client(const char16_t* identifier, +shared_ptr Lobby::find_client(const u16string* identifier, uint64_t serial_number) { for (size_t x = 0; x < this->max_clients; x++) { if (!this->clients[x]) { @@ -145,7 +145,7 @@ shared_ptr Lobby::find_client(const char16_t* identifier, (this->clients[x]->license->serial_number == serial_number)) { 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]; } } diff --git a/src/Lobby.hh b/src/Lobby.hh index 450b0e63..eddb06a4 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -73,7 +73,8 @@ struct Lobby { void move_client_to_lobby(std::shared_ptr dest_lobby, std::shared_ptr c); - std::shared_ptr find_client(const char16_t* identifier = nullptr, + std::shared_ptr find_client( + const std::u16string* identifier = nullptr, uint64_t serial_number = 0); void add_item(const PlayerInventoryItem& item); diff --git a/src/Map.cc b/src/Map.cc index 85fbbeeb..3af41cde 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -433,7 +433,7 @@ static vector parse_map(uint8_t episode, uint8_t difficulty, return enemies; } -vector load_map(const char* filename, uint8_t episode, +vector load_map(const std::string& filename, uint8_t episode, uint8_t difficulty, const BattleParams* battle_params, bool alt_enemies) { shared_ptr data = file_cache.get(filename); const EnemyEntry* entries = reinterpret_cast(data->data()); diff --git a/src/Map.hh b/src/Map.hh index fdc0a326..7ffc0a0c 100644 --- a/src/Map.hh +++ b/src/Map.hh @@ -48,5 +48,5 @@ struct PSOEnemy { PSOEnemy(uint32_t experience, uint32_t rt_index); } __attribute__((packed)); -std::vector load_map(const char* filename, uint8_t episode, +std::vector load_map(const std::string& filename, uint8_t episode, uint8_t difficulty, const BattleParams* bp, bool alt_enemies); diff --git a/src/Player.hh b/src/Player.hh index 31b8cb91..b456df6e 100644 --- a/src/Player.hh +++ b/src/Player.hh @@ -71,7 +71,8 @@ struct PlayerBank { void load(const std::string& filename); 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 remove_item(uint32_t item_id, uint32_t amount, PlayerBankItem* item); diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index d175b3f2..68889b5c 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -251,9 +251,8 @@ void ProxyServer::UnlinkedSession::on_client_input() { throw runtime_error("command is not 9D"); } const auto& cmd = check_size_t(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( - serial_number, cmd.access_key.c_str(), nullptr); + stoul(cmd.serial_number, nullptr, 16), cmd.access_key); sub_version = cmd.sub_version; character_name = cmd.name; @@ -264,9 +263,8 @@ void ProxyServer::UnlinkedSession::on_client_input() { throw runtime_error("command is not 9E"); } const auto& cmd = check_size_t(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( - serial_number, cmd.access_key.c_str(), nullptr); + stoul(cmd.serial_number, nullptr, 16), cmd.access_key); sub_version = cmd.sub_version; character_name = cmd.name; client_config = cmd.client_config.cfg; diff --git a/src/Quest.cc b/src/Quest.cc index f7b1c13b..a3978593 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -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); vector filenames(filename_set.begin(), filename_set.end()); sort(filenames.begin(), filenames.end()); diff --git a/src/Quest.hh b/src/Quest.hh index 932c94d1..971c9eaa 100644 --- a/src/Quest.hh +++ b/src/Quest.hh @@ -80,7 +80,7 @@ struct QuestIndex { std::map> gba_file_contents; - QuestIndex(const char* directory); + QuestIndex(const std::string& directory); std::shared_ptr get(GameVersion version, uint32_t id) const; std::shared_ptr get_gba(const std::string& name) const; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 8736ea8d..f8fe00e6 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -24,6 +24,10 @@ using namespace std; +extern FileContentsCache file_cache; + + + enum ClientStateBB { // initial connection. server will redirect client to another port. INITIAL_LOGIN = 0x00, @@ -201,10 +205,10 @@ void process_verify_license_gc(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // DB const auto& cmd = check_size_t(data); - uint32_t serial_number = strtoul(cmd.serial_number.c_str(), nullptr, 16); + uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16); try { - c->license = s->license_manager->verify_gc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str()); + c->license = s->license_manager->verify_gc(serial_number, cmd.access_key, + cmd.password); } catch (const exception& e) { if (!s->allow_unregistered_users) { u16string message = u"Login failed: " + decode_sjis(e.what()); @@ -212,8 +216,8 @@ void process_verify_license_gc(shared_ptr s, shared_ptr c, c->should_disconnect = true; return; } else { - auto l = LicenseManager::create_license_gc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str(), true); + auto l = LicenseManager::create_license_gc(serial_number, cmd.access_key, + cmd.password, true); s->license_manager->add(l); c->license = l; } @@ -229,14 +233,12 @@ void process_login_a_dc_pc_gc(shared_ptr s, shared_ptr c, 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 { if (c->version == GameVersion::GC) { - c->license = s->license_manager->verify_gc(serial_number, - cmd.access_key.c_str(), nullptr); + c->license = s->license_manager->verify_gc(serial_number, cmd.access_key); } else { - c->license = s->license_manager->verify_pc(serial_number, - cmd.access_key.c_str(), nullptr); + c->license = s->license_manager->verify_pc(serial_number, cmd.access_key); } } catch (const exception& e) { // 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 s, shared_ptr c, 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 { if (c->version == GameVersion::GC) { - c->license = s->license_manager->verify_gc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str()); + c->license = s->license_manager->verify_gc(serial_number, cmd.access_key, + cmd.password); } else { - c->license = s->license_manager->verify_pc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str()); + c->license = s->license_manager->verify_pc(serial_number, cmd.access_key); } } catch (const exception& e) { if (!s->allow_unregistered_users) { @@ -276,11 +277,11 @@ void process_login_c_dc_pc_gc(shared_ptr s, shared_ptr c, } else { shared_ptr l; if (c->version == GameVersion::GC) { - l = LicenseManager::create_license_gc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str(), true); + l = LicenseManager::create_license_gc(serial_number, cmd.access_key, + cmd.password, true); } else { - l = LicenseManager::create_license_pc(serial_number, - cmd.access_key.c_str(), cmd.password.c_str(), true); + l = LicenseManager::create_license_pc(serial_number, cmd.access_key, + true); } s->license_manager->add(l); c->license = l; @@ -322,14 +323,14 @@ void process_login_d_e_pc_gc(shared_ptr s, shared_ptr c, 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 { if (c->version == GameVersion::GC) { c->license = s->license_manager->verify_gc(serial_number, - base_cmd->access_key.c_str(), nullptr); + base_cmd->access_key); } else { c->license = s->license_manager->verify_pc(serial_number, - base_cmd->access_key.c_str(), nullptr); + base_cmd->access_key); } } catch (const exception& e) { // See comment in 9A handler about why we do this even if unregistered users @@ -356,8 +357,7 @@ void process_login_bb(shared_ptr s, shared_ptr c, c->flags |= flags_for_version(c->version, 0); try { - c->license = s->license_manager->verify_bb( - cmd.username.c_str(), cmd.password.c_str()); + c->license = s->license_manager->verify_bb(cmd.username, cmd.password); } catch (const exception& e) { u16string message = u"Login failed: " + decode_sjis(e.what()); send_message_box(c, message.c_str()); @@ -1150,7 +1150,7 @@ void process_chat_generic(shared_ptr s, shared_ptr c, if (processed_text[0] == L'$') { auto l = s->find_lobby(c->lobby_id); if (l) { - process_chat_command(s, l, c, &processed_text[1]); + process_chat_command(s, l, c, processed_text); } } else { if (!c->can_chat) { @@ -1413,13 +1413,12 @@ void process_simple_mail(shared_ptr s, shared_ptr c, // If the target has auto-reply enabled, send the autoreply if (!target->player.auto_reply.empty()) { 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 - u16string u16message = decode_sjis(cmd.text); - send_simple_mail(target, c->license->serial_number, - c->player.disp.name.c_str(), u16message.c_str()); + u16string msg = decode_sjis(cmd.text); + send_simple_mail(target, c->license->serial_number, c->player.disp.name, msg); } @@ -1469,9 +1468,9 @@ void process_set_blocked_senders_list(shared_ptr, shared_ptr create_game_generic(shared_ptr s, - shared_ptr c, const char16_t* name, const char16_t* password, - uint8_t episode, uint8_t difficulty, uint8_t battle, uint8_t challenge, - uint8_t solo) { + shared_ptr c, const std::u16string& name, + const std::u16string& password, uint8_t episode, uint8_t difficulty, + uint8_t battle, uint8_t challenge, uint8_t solo) { 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, @@ -1617,7 +1616,7 @@ void process_create_game_pc(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // C1 const auto& cmd = check_size_t(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); s->add_lobby(game); @@ -1658,9 +1657,8 @@ void process_create_game_bb(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // C1 const auto& cmd = check_size_t(data); - auto game = create_game_generic(s, c, cmd.name.c_str(), cmd.password.c_str(), - cmd.episode, cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, - cmd.solo_mode); + auto game = create_game_generic(s, c, cmd.name, cmd.password, cmd.episode, + cmd.difficulty, cmd.battle_mode, cmd.challenge_mode, cmd.solo_mode); s->add_lobby(game); s->change_client_lobby(c, game); @@ -1751,12 +1749,10 @@ independently.\r\n\ message += u"License check "; try { if (c->flags & Client::Flag::BB_PATCH) { - c->license = s->license_manager->verify_bb( - cmd.username.c_str(), cmd.password.c_str()); + c->license = s->license_manager->verify_bb(cmd.username, cmd.password); } else { - uint32_t serial_number = strtoul(cmd.username.c_str(), nullptr, 16); c->license = s->license_manager->verify_pc( - serial_number, cmd.password.c_str(), nullptr); + stoul(cmd.username, nullptr, 16), cmd.password); } message += u"OK"; } catch (const exception& e) { diff --git a/src/SendCommands.cc b/src/SendCommands.cc index a65d2974..1a5a173b 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -348,7 +348,8 @@ void send_stream_file_bb(shared_ptr c) { uint32_t buffer_offset = 0; 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); size_t file_data_remaining = file_data->size(); @@ -395,7 +396,7 @@ void send_complete_player_bb(shared_ptr c) { //////////////////////////////////////////////////////////////////////////////// // patch functions -void send_check_directory_patch(shared_ptr c, const char* dir) { +void send_check_directory_patch(shared_ptr c, const string& dir) { S_CheckDirectory_Patch_09 cmd = {dir}; send_command(c, 0x09, 0x00, cmd); } @@ -406,12 +407,12 @@ void send_check_directory_patch(shared_ptr c, const char* dir) { // message functions void send_text(shared_ptr c, StringWriter& w, uint16_t command, - const char16_t* text) { + const u16string& text) { if ((c->version == GameVersion::DC) || (c->version == GameVersion::GC)) { string data = encode_sjis(text); add_color(w, data.c_str(), data.size()); } else { - add_color(w, text, text_strlen_t(text)); + add_color(w, text.c_str(), text.size()); } while (w.str().size() & 3) { w.put_u8(0); @@ -420,44 +421,44 @@ void send_text(shared_ptr c, StringWriter& w, uint16_t command, } void send_header_text(shared_ptr c, uint16_t command, - uint32_t guild_card_number, const char16_t* text) { + uint32_t guild_card_number, const u16string& text) { StringWriter w; w.put(SC_TextHeader_01_06_11_B0({0, guild_card_number})); send_text(c, w, command, text); } void send_text(shared_ptr c, uint16_t command, - const char16_t* text) { + const u16string& text) { StringWriter w; send_text(c, w, command, text); } -void send_message_box(shared_ptr c, const char16_t* text) { +void send_message_box(shared_ptr c, const u16string& text) { uint16_t command = (c->version == GameVersion::PATCH) ? 0x13 : 0x1A; send_text(c, command, text); } -void send_lobby_name(shared_ptr c, const char16_t* text) { +void send_lobby_name(shared_ptr c, const u16string& text) { send_text(c, 0x8A, text); } -void send_quest_info(shared_ptr c, const char16_t* text) { +void send_quest_info(shared_ptr c, const u16string& text) { send_text(c, 0xA3, text); } -void send_lobby_message_box(shared_ptr c, const char16_t* text) { +void send_lobby_message_box(shared_ptr c, const u16string& text) { send_header_text(c, 0x01, 0, text); } -void send_ship_info(shared_ptr c, const char16_t* text) { +void send_ship_info(shared_ptr c, const u16string& text) { send_header_text(c, 0x11, 0, text); } -void send_text_message(shared_ptr c, const char16_t* text) { +void send_text_message(shared_ptr c, const u16string& text) { send_header_text(c, 0xB0, 0, text); } -void send_text_message(shared_ptr l, const char16_t* text) { +void send_text_message(shared_ptr l, const u16string& text) { for (size_t x = 0; x < l->max_clients; x++) { if (l->clients[x]) { send_text_message(l->clients[x], text); @@ -465,7 +466,7 @@ void send_text_message(shared_ptr l, const char16_t* text) { } } -void send_text_message(shared_ptr s, const char16_t* text) { +void send_text_message(shared_ptr s, const u16string& text) { // TODO: We should have a collection of all clients (even those not in any // lobby) and use that instead here for (auto& l : s->all_lobbies()) { @@ -474,7 +475,7 @@ void send_text_message(shared_ptr s, const char16_t* text) { } void send_chat_message(shared_ptr 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; if (c->version == GameVersion::BB) { data.append(u"\x09J"); @@ -482,11 +483,11 @@ void send_chat_message(shared_ptr c, uint32_t from_guild_card_number, data.append(remove_language_marker(from_name)); data.append(u"\x09\x09J"); 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 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; cmd.player_tag = 0x00010000; cmd.from_guild_card_number = from_guild_card_number; @@ -497,7 +498,7 @@ void send_simple_mail_gc(std::shared_ptr c, uint32_t from_guild_card_num } void send_simple_mail(std::shared_ptr 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) { send_simple_mail_gc(c, from_guild_card_number, from_name, text); } else { @@ -652,7 +653,7 @@ void send_guild_card(shared_ptr c, shared_ptr source) { template void send_menu_t( shared_ptr c, - const char16_t* menu_name, + const u16string& menu_name, uint32_t menu_id, const vector& items, bool is_info_menu) { @@ -684,7 +685,7 @@ void send_menu_t( send_command(c, is_info_menu ? 0x1F : 0x07, entries.size() - 1, entries); } -void send_menu(shared_ptr c, const char16_t* menu_name, +void send_menu(shared_ptr c, const u16string& menu_name, uint32_t menu_id, const vector& items, bool is_info_menu) { if (c->version == GameVersion::PC || c->version == GameVersion::PATCH || c->version == GameVersion::BB) { @@ -1306,7 +1307,7 @@ void send_quest_open_file_t( void send_quest_file_chunk( shared_ptr c, - const char* filename, + const string& filename, size_t chunk_index, const void* data, size_t size, diff --git a/src/SendCommands.hh b/src/SendCommands.hh index 3529d49e..f3a5d56a 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -86,20 +86,20 @@ void send_stream_file_bb(std::shared_ptr c); void send_approve_player_choice_bb(std::shared_ptr c); void send_complete_player_bb(std::shared_ptr c); -void send_check_directory_patch(std::shared_ptr c, const char* dir); +void send_check_directory_patch(std::shared_ptr c, const std::string& dir); -void send_message_box(std::shared_ptr c, const char16_t* text); -void send_lobby_name(std::shared_ptr c, const char16_t* text); -void send_quest_info(std::shared_ptr c, const char16_t* text); -void send_lobby_message_box(std::shared_ptr c, const char16_t* text); -void send_ship_info(std::shared_ptr c, const char16_t* text); -void send_text_message(std::shared_ptr c, const char16_t* text); -void send_text_message(std::shared_ptr l, const char16_t* text); -void send_text_message(std::shared_ptr l, const char16_t* text); +void send_message_box(std::shared_ptr c, const std::u16string& text); +void send_lobby_name(std::shared_ptr c, const std::u16string& text); +void send_quest_info(std::shared_ptr c, const std::u16string& text); +void send_lobby_message_box(std::shared_ptr c, const std::u16string& text); +void send_ship_info(std::shared_ptr c, const std::u16string& text); +void send_text_message(std::shared_ptr c, const std::u16string& text); +void send_text_message(std::shared_ptr l, const std::u16string& text); +void send_text_message(std::shared_ptr l, const std::u16string& text); void send_chat_message(std::shared_ptr 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 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 __attribute__((format(printf, 2, 3))) void send_text_message_printf( @@ -121,7 +121,7 @@ void send_card_search_result( std::shared_ptr result_lobby); void send_guild_card(std::shared_ptr c, std::shared_ptr source); -void send_menu(std::shared_ptr c, const char16_t* menu_name, +void send_menu(std::shared_ptr c, const std::u16string& menu_name, uint32_t menu_id, const std::vector& items, bool is_info_menu); void send_game_menu(std::shared_ptr c, std::shared_ptr s); void send_quest_menu(std::shared_ptr c, uint32_t menu_id, diff --git a/src/ServerState.cc b/src/ServerState.cc index 8156c7f7..37981453 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -146,13 +146,12 @@ void ServerState::remove_lobby(uint32_t lobby_id) { this->id_to_lobby.erase(lobby_id); } -shared_ptr ServerState::find_client(const char16_t* identifier, +shared_ptr ServerState::find_client(const std::u16string* identifier, uint64_t serial_number, shared_ptr l) { if ((serial_number == 0) && identifier) { try { - string encoded = encode_sjis(identifier); - serial_number = stoull(encoded, nullptr, 0); + serial_number = stoull(encode_sjis(*identifier), nullptr, 0); } catch (const exception&) { } } diff --git a/src/ServerState.hh b/src/ServerState.hh index de797f8d..808fcb53 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -94,8 +94,10 @@ struct ServerState { void add_lobby(std::shared_ptr l); void remove_lobby(uint32_t lobby_id); - std::shared_ptr find_client(const char16_t* identifier = nullptr, - uint64_t serial_number = 0, std::shared_ptr l = nullptr); + std::shared_ptr find_client( + const std::u16string* identifier = nullptr, + uint64_t serial_number = 0, + std::shared_ptr l = nullptr); uint32_t connect_address_for_client(std::shared_ptr c);