diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..53cf98c1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,28 @@ +Standard: c++20 +BasedOnStyle: LLVM +IndentWidth: 2 +ColumnLimit: 0 +AccessModifierOffset: -2 +NamespaceIndentation: None +BreakBeforeBraces: Custom +PointerAlignment: Left +IndentCaseLabels: true +PackConstructorInitializers: CurrentLine +BraceWrapping: + AfterEnum: false + AfterStruct: false + AfterClass: false + SplitEmptyFunction: false + AfterControlStatement: false + AfterNamespace: false + AfterFunction: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +AlignTrailingComments: false +AlignAfterOpenBracket: DontAlign +AlignOperands: DontAlign +AlignEscapedNewlines: Left diff --git a/src/BMLArchive.cc b/src/BMLArchive.cc index c9020f62..81508215 100644 --- a/src/BMLArchive.cc +++ b/src/BMLArchive.cc @@ -8,8 +8,6 @@ using namespace std; - - template struct BMLHeader { using U32T = typename std::conditional::type; @@ -54,13 +52,12 @@ void BMLArchive::load_t() { size_t gvm_offset = offset; offset = (offset + entry.compressed_gvm_size + 0x1F) & (~0x1F); - this->entries.emplace(entry.filename, Entry{ - data_offset, entry.compressed_size, gvm_offset, entry.compressed_gvm_size}); + this->entries.emplace(entry.filename, Entry{data_offset, entry.compressed_size, gvm_offset, entry.compressed_gvm_size}); } } BMLArchive::BMLArchive(shared_ptr data, bool big_endian) - : data(data) { + : data(data) { if (big_endian) { this->load_t(); } else { diff --git a/src/BMLArchive.hh b/src/BMLArchive.hh index a29fec31..4eafad1a 100644 --- a/src/BMLArchive.hh +++ b/src/BMLArchive.hh @@ -8,8 +8,6 @@ #include #include - - class BMLArchive { public: BMLArchive(std::shared_ptr data, bool big_endian); diff --git a/src/CatSession.cc b/src/CatSession.cc index d00475dc..e49b4a94 100644 --- a/src/CatSession.cc +++ b/src/CatSession.cc @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -24,29 +24,27 @@ #include "Loggers.hh" #include "PSOProtocol.hh" -#include "SendCommands.hh" +#include "ProxyCommands.hh" #include "ReceiveCommands.hh" #include "ReceiveSubcommands.hh" -#include "ProxyCommands.hh" +#include "SendCommands.hh" using namespace std; - - CatSession::CatSession( shared_ptr base, const struct sockaddr_storage& remote, GameVersion version, shared_ptr bb_key_file) - : Shell(base), - log("[CatSession] ", proxy_server_log.min_level), - channel( - version, - CatSession::dispatch_on_channel_input, - CatSession::dispatch_on_channel_error, - this, - "CatSession"), - bb_key_file(bb_key_file) { + : Shell(base), + log("[CatSession] ", proxy_server_log.min_level), + channel( + version, + CatSession::dispatch_on_channel_input, + CatSession::dispatch_on_channel_error, + this, + "CatSession"), + bb_key_file(bb_key_file) { if (remote.ss_family != AF_INET) { throw runtime_error("remote is not AF_INET"); } @@ -62,7 +60,7 @@ CatSession::CatSession( this->channel.set_bufferevent(bev); if (bufferevent_socket_connect(this->channel.bev.get(), - reinterpret_cast(&remote), sizeof(struct sockaddr_in)) != 0) { + reinterpret_cast(&remote), sizeof(struct sockaddr_in)) != 0) { throw runtime_error(string_printf("failed to connect (%d)", EVUTIL_SOCKET_ERROR())); } } @@ -133,7 +131,7 @@ void CatSession::on_channel_error(short events) { } } -void CatSession::print_prompt() { } +void CatSession::print_prompt() {} void CatSession::execute_command(const std::string& command) { string full_cmd = parse_data_string(command, nullptr, ParseDataFlags::ALLOW_FILES); diff --git a/src/CatSession.hh b/src/CatSession.hh index 01013831..a3873680 100644 --- a/src/CatSession.hh +++ b/src/CatSession.hh @@ -2,22 +2,20 @@ #include -#include -#include -#include #include -#include -#include +#include #include #include +#include +#include +#include +#include #include "PSOEncryption.hh" #include "PSOProtocol.hh" #include "ServerState.hh" #include "Shell.hh" - - class CatSession : public Shell { public: CatSession( diff --git a/src/Channel.cc b/src/Channel.cc index bfb3a80c..6f994ff9 100644 --- a/src/Channel.cc +++ b/src/Channel.cc @@ -1,9 +1,9 @@ #include "Channel.hh" +#include #include #include #include -#include #include #include @@ -15,19 +15,13 @@ using namespace std; - - extern bool use_terminal_colors; - - static void flush_and_free_bufferevent(struct bufferevent* bev) { bufferevent_flush(bev, EV_READ | EV_WRITE, BEV_FINISHED); bufferevent_free(bev); } - - Channel::Channel( GameVersion version, on_command_received_t on_command_received, @@ -36,14 +30,14 @@ Channel::Channel( const string& name, TerminalFormat terminal_send_color, TerminalFormat terminal_recv_color) - : bev(nullptr, flush_and_free_bufferevent), - version(version), - name(name), - terminal_send_color(terminal_send_color), - terminal_recv_color(terminal_recv_color), - on_command_received(on_command_received), - on_error(on_error), - context_obj(context_obj) { + : bev(nullptr, flush_and_free_bufferevent), + version(version), + name(name), + terminal_send_color(terminal_send_color), + terminal_recv_color(terminal_recv_color), + on_command_received(on_command_received), + on_error(on_error), + context_obj(context_obj) { } Channel::Channel( @@ -55,14 +49,14 @@ Channel::Channel( const string& name, TerminalFormat terminal_send_color, TerminalFormat terminal_recv_color) - : bev(nullptr, flush_and_free_bufferevent), - version(version), - name(name), - terminal_send_color(terminal_send_color), - terminal_recv_color(terminal_recv_color), - on_command_received(on_command_received), - on_error(on_error), - context_obj(context_obj) { + : bev(nullptr, flush_and_free_bufferevent), + version(version), + name(name), + terminal_send_color(terminal_send_color), + terminal_recv_color(terminal_recv_color), + on_command_received(on_command_received), + on_error(on_error), + context_obj(context_obj) { this->set_bufferevent(bev); } @@ -114,8 +108,6 @@ void Channel::set_bufferevent(struct bufferevent* bev) { } } - - void Channel::disconnect() { if (this->bev.get()) { // If the output buffer is not empty, move the bufferevent into the draining @@ -157,15 +149,12 @@ void Channel::disconnect() { this->crypt_out.reset(); } - - Channel::Message Channel::recv(bool print_contents) { struct evbuffer* buf = bufferevent_get_input(this->bev.get()); size_t header_size = (this->version == GameVersion::BB) ? 8 : 4; PSOCommandHeader header; - if (evbuffer_copyout(buf, &header, header_size) - < static_cast(header_size)) { + if (evbuffer_copyout(buf, &header, header_size) < static_cast(header_size)) { throw out_of_range("no command available"); } @@ -179,7 +168,8 @@ Channel::Message Channel::recv(bool print_contents) { // is not reflected in the size field. This logic does not occur if encryption // is not yet enabled. size_t command_physical_size = (this->crypt_in.get() && (version == GameVersion::BB)) - ? ((command_logical_size + 7) & ~7) : command_logical_size; + ? ((command_logical_size + 7) & ~7) + : command_logical_size; if (evbuffer_get_length(buf) < command_physical_size) { throw out_of_range("no command available"); } @@ -190,8 +180,7 @@ Channel::Message Channel::recv(bool print_contents) { // consistent state. string header_data(header_size, '\0'); - if (evbuffer_remove(buf, header_data.data(), header_data.size()) - < static_cast(header_data.size())) { + if (evbuffer_remove(buf, header_data.data(), header_data.size()) < static_cast(header_data.size())) { throw logic_error("enough bytes available, but could not remove them"); } if (this->crypt_in.get()) { @@ -199,8 +188,7 @@ Channel::Message Channel::recv(bool print_contents) { } string command_data(command_physical_size - header_size, '\0'); - if (evbuffer_remove(buf, command_data.data(), command_data.size()) - < static_cast(command_data.size())) { + if (evbuffer_remove(buf, command_data.data(), command_data.size()) < static_cast(command_data.size())) { throw logic_error("enough bytes available, but could not remove them"); } @@ -222,12 +210,14 @@ Channel::Message Channel::recv(bool print_contents) { } if (version == GameVersion::BB) { - command_data_log.info("Received from %s (version=BB command=%04hX flag=%08" PRIX32 ")", + command_data_log.info( + "Received from %s (version=BB command=%04hX flag=%08" PRIX32 ")", this->name.c_str(), header.command(this->version), header.flag(this->version)); } else { - command_data_log.info("Received from %s (version=%s command=%02hX flag=%02" PRIX32 ")", + command_data_log.info( + "Received from %s (version=%s command=%02hX flag=%02" PRIX32 ")", this->name.c_str(), name_for_version(this->version), header.command(this->version), @@ -245,9 +235,9 @@ Channel::Message Channel::recv(bool print_contents) { } return { - .command = header.command(this->version), - .flag = header.flag(this->version), - .data = move(command_data), + .command = header.command(this->version), + .flag = header.flag(this->version), + .data = move(command_data), }; } @@ -376,8 +366,6 @@ void Channel::send(const string& data, bool print_contents) { return this->send(data.data(), data.size(), print_contents); } - - void Channel::dispatch_on_input(struct bufferevent*, void* ctx) { Channel* ch = reinterpret_cast(ctx); // The client can be disconnected during on_command_received, so we have to diff --git a/src/Channel.hh b/src/Channel.hh index dc9a0096..98af38da 100644 --- a/src/Channel.hh +++ b/src/Channel.hh @@ -9,8 +9,6 @@ #include "PSOProtocol.hh" #include "Version.hh" - - struct Channel { std::unique_ptr bev; struct sockaddr_storage local_addr; diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 5a035a82..c4a42142 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -2,12 +2,12 @@ #include -#include -#include -#include #include #include #include +#include +#include +#include #include "Client.hh" #include "Lobby.hh" @@ -21,16 +21,12 @@ using namespace std; - - //////////////////////////////////////////////////////////////////////////////// // Checks - - class precondition_failed { public: - precondition_failed(const std::u16string& user_msg) : user_msg(user_msg) { } + precondition_failed(const std::u16string& user_msg) : user_msg(user_msg) {} ~precondition_failed() = default; const std::u16string& what() const { @@ -64,17 +60,13 @@ static void check_not_version(shared_ptr c, GameVersion version) { static void check_is_game(shared_ptr l, bool is_game) { if (l->is_game() != is_game) { - throw precondition_failed(is_game ? - u"$C6This command cannot\nbe used in lobbies." : - u"$C6This command cannot\nbe used in games."); + throw precondition_failed(is_game ? u"$C6This command cannot\nbe used in lobbies." : u"$C6This command cannot\nbe used in games."); } } static void check_is_ep3(shared_ptr c, bool is_ep3) { if (!!(c->flags & Client::Flag::IS_EPISODE_3) != is_ep3) { - throw precondition_failed(is_ep3 ? - u"$C6This command can only\nbe used in Episode 3." : - u"$C6This command cannot\nbe used in Episode 3."); + throw precondition_failed(is_ep3 ? u"$C6This command can only\nbe used in Episode 3." : u"$C6This command cannot\nbe used in Episode 3."); } } @@ -90,8 +82,6 @@ static void check_is_leader(shared_ptr l, shared_ptr c) { } } - - //////////////////////////////////////////////////////////////////////////////// // Message commands @@ -888,7 +878,8 @@ static void server_command_ban(shared_ptr s, shared_ptr l, uint64_t usecs = stoull(encode_sjis(args), nullptr, 0) * 1000000; size_t unit_offset = 0; - for (; isdigit(args[unit_offset]); unit_offset++); + for (; isdigit(args[unit_offset]); unit_offset++) + ; if (args[unit_offset] == 'm') { usecs *= 60; } else if (args[unit_offset] == 'h') { @@ -1160,8 +1151,6 @@ static void proxy_command_item(shared_ptr, } } - - //////////////////////////////////////////////////////////////////////////////// typedef void (*server_handler_t)(shared_ptr s, shared_ptr l, @@ -1176,46 +1165,46 @@ struct ChatCommandDefinition { static const unordered_map chat_commands({ // TODO: implement command_help and actually use the usage strings here - {u"$allevent", {server_command_lobby_event_all, nullptr, u"Usage:\nallevent "}}, - {u"$ann", {server_command_announce, nullptr, u"Usage:\nann "}}, - {u"$arrow", {server_command_arrow, proxy_command_arrow, u"Usage:\narrow "}}, - {u"$auction", {server_command_auction, proxy_command_auction, u"Usage:\nauction"}}, - {u"$ax", {server_command_ax, nullptr, u"Usage:\nax "}}, - {u"$ban", {server_command_ban, nullptr, u"Usage:\nban "}}, + {u"$allevent", {server_command_lobby_event_all, nullptr, u"Usage:\nallevent "}}, + {u"$ann", {server_command_announce, nullptr, u"Usage:\nann "}}, + {u"$arrow", {server_command_arrow, proxy_command_arrow, u"Usage:\narrow "}}, + {u"$auction", {server_command_auction, proxy_command_auction, u"Usage:\nauction"}}, + {u"$ax", {server_command_ax, nullptr, u"Usage:\nax "}}, + {u"$ban", {server_command_ban, nullptr, u"Usage:\nban "}}, // TODO: implement this on proxy server - {u"$bbchar", {server_command_convert_char_to_bb, nullptr, u"Usage:\nbbchar <1-4>"}}, - {u"$cheat", {server_command_cheat, nullptr, u"Usage:\ncheat"}}, - {u"$debug", {server_command_debug, nullptr, u"Usage:\ndebug"}}, - {u"$edit", {server_command_edit, nullptr , u"Usage:\nedit "}}, - {u"$event", {server_command_lobby_event, proxy_command_lobby_event, u"Usage:\nevent "}}, - {u"$exit", {server_command_exit, proxy_command_exit, u"Usage:\nexit"}}, - {u"$gc", {server_command_get_self_card, proxy_command_get_player_card, u"Usage:\ngc"}}, - {u"$infhp", {server_command_infinite_hp, proxy_command_infinite_hp, u"Usage:\ninfhp"}}, - {u"$inftp", {server_command_infinite_tp, proxy_command_infinite_tp, u"Usage:\ninftp"}}, - {u"$item", {server_command_item, proxy_command_item, u"Usage:\nitem "}}, - {u"$i", {server_command_item, proxy_command_item, u"Usage:\ni "}}, - {u"$kick", {server_command_kick, nullptr, u"Usage:\nkick "}}, - {u"$li", {server_command_lobby_info, proxy_command_lobby_info, u"Usage:\nli"}}, - {u"$maxlevel", {server_command_max_level, nullptr, u"Usage:\nmax_level "}}, - {u"$minlevel", {server_command_min_level, nullptr, u"Usage:\nmin_level "}}, - {u"$next", {server_command_next, proxy_command_next, u"Usage:\nnext"}}, - {u"$password", {server_command_password, nullptr, u"Usage:\nlock [password]\nomit password to\nunlock game"}}, - {u"$patch", {server_command_patch, proxy_command_patch, u"Usage:\npatch "}}, - {u"$persist", {server_command_persist, nullptr, u"Usage:\npersist"}}, - {u"$playrec", {server_command_playrec, nullptr, u"Usage:\nplayrec "}}, - {u"$rand", {server_command_rand, proxy_command_rand, u"Usage:\nrand [hex seed]\nomit seed to revert\nto default"}}, - {u"$saverec", {server_command_saverec, nullptr, u"Usage:\nsaverec "}}, - {u"$sc", {server_command_send_client, proxy_command_send_client, u"Usage:\nsc "}}, - {u"$secid", {server_command_secid, proxy_command_secid, u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}}, - {u"$silence", {server_command_silence, nullptr, u"Usage:\nsilence "}}, + {u"$bbchar", {server_command_convert_char_to_bb, nullptr, u"Usage:\nbbchar <1-4>"}}, + {u"$cheat", {server_command_cheat, nullptr, u"Usage:\ncheat"}}, + {u"$debug", {server_command_debug, nullptr, u"Usage:\ndebug"}}, + {u"$edit", {server_command_edit, nullptr, u"Usage:\nedit "}}, + {u"$event", {server_command_lobby_event, proxy_command_lobby_event, u"Usage:\nevent "}}, + {u"$exit", {server_command_exit, proxy_command_exit, u"Usage:\nexit"}}, + {u"$gc", {server_command_get_self_card, proxy_command_get_player_card, u"Usage:\ngc"}}, + {u"$infhp", {server_command_infinite_hp, proxy_command_infinite_hp, u"Usage:\ninfhp"}}, + {u"$inftp", {server_command_infinite_tp, proxy_command_infinite_tp, u"Usage:\ninftp"}}, + {u"$item", {server_command_item, proxy_command_item, u"Usage:\nitem "}}, + {u"$i", {server_command_item, proxy_command_item, u"Usage:\ni "}}, + {u"$kick", {server_command_kick, nullptr, u"Usage:\nkick "}}, + {u"$li", {server_command_lobby_info, proxy_command_lobby_info, u"Usage:\nli"}}, + {u"$maxlevel", {server_command_max_level, nullptr, u"Usage:\nmax_level "}}, + {u"$minlevel", {server_command_min_level, nullptr, u"Usage:\nmin_level "}}, + {u"$next", {server_command_next, proxy_command_next, u"Usage:\nnext"}}, + {u"$password", {server_command_password, nullptr, u"Usage:\nlock [password]\nomit password to\nunlock game"}}, + {u"$patch", {server_command_patch, proxy_command_patch, u"Usage:\npatch "}}, + {u"$persist", {server_command_persist, nullptr, u"Usage:\npersist"}}, + {u"$playrec", {server_command_playrec, nullptr, u"Usage:\nplayrec "}}, + {u"$rand", {server_command_rand, proxy_command_rand, u"Usage:\nrand [hex seed]\nomit seed to revert\nto default"}}, + {u"$saverec", {server_command_saverec, nullptr, u"Usage:\nsaverec "}}, + {u"$sc", {server_command_send_client, proxy_command_send_client, u"Usage:\nsc "}}, + {u"$secid", {server_command_secid, proxy_command_secid, u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}}, + {u"$silence", {server_command_silence, nullptr, u"Usage:\nsilence "}}, // TODO: implement this on proxy server - {u"$song", {server_command_song, proxy_command_song, u"Usage:\nsong "}}, - {u"$spec", {server_command_spec, nullptr, u"Usage:\nspec"}}, - {u"$ss", {nullptr, proxy_command_send_server, u"Usage:\nss "}}, - {u"$swa", {server_command_switch_assist, proxy_command_switch_assist, u"Usage:\nswa"}}, - {u"$type", {server_command_lobby_type, nullptr, u"Usage:\ntype "}}, - {u"$warp", {server_command_warp, proxy_command_warp, u"Usage:\nwarp "}}, - {u"$what", {server_command_what, nullptr, u"Usage:\nwhat"}}, + {u"$song", {server_command_song, proxy_command_song, u"Usage:\nsong "}}, + {u"$spec", {server_command_spec, nullptr, u"Usage:\nspec"}}, + {u"$ss", {nullptr, proxy_command_send_server, u"Usage:\nss "}}, + {u"$swa", {server_command_switch_assist, proxy_command_switch_assist, u"Usage:\nswa"}}, + {u"$type", {server_command_lobby_type, nullptr, u"Usage:\ntype "}}, + {u"$warp", {server_command_warp, proxy_command_warp, u"Usage:\nwarp "}}, + {u"$what", {server_command_what, nullptr, u"Usage:\nwhat"}}, }); struct SplitCommand { diff --git a/src/ChatCommands.hh b/src/ChatCommands.hh index 107c8c34..7d669ef0 100644 --- a/src/ChatCommands.hh +++ b/src/ChatCommands.hh @@ -5,10 +5,10 @@ #include #include -#include "ServerState.hh" -#include "Lobby.hh" #include "Client.hh" +#include "Lobby.hh" #include "ProxyServer.hh" +#include "ServerState.hh" void on_chat_command(std::shared_ptr s, std::shared_ptr l, std::shared_ptr c, const std::u16string& text); diff --git a/src/Client.cc b/src/Client.cc index efeba819..38ee682b 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -1,9 +1,9 @@ #include "Client.hh" +#include #include #include #include -#include #include #include @@ -16,71 +16,64 @@ using namespace std; - - const uint64_t CLIENT_CONFIG_MAGIC = 0x492A890E82AC9839; -FileContentsCache client_options_cache(3600000000ULL); static atomic next_id(1); - - ClientOptions::ClientOptions() - : switch_assist(false), - infinite_hp(false), - infinite_tp(false), - debug(false), - override_section_id(-1), - override_lobby_event(-1), - override_lobby_number(-1), - override_random_seed(-1), - save_files(false), - enable_chat_commands(true), - enable_chat_filter(true), - enable_player_notifications(false), - suppress_remote_login(false), - zero_remote_guild_card(false), - ep3_infinite_meseta(false), - red_name(false), - blank_name(false), - function_call_return_value(-1) { } - - + : switch_assist(false), + infinite_hp(false), + infinite_tp(false), + debug(false), + override_section_id(-1), + override_lobby_event(-1), + override_lobby_number(-1), + override_random_seed(-1), + save_files(false), + enable_chat_commands(true), + enable_chat_filter(true), + enable_player_notifications(false), + suppress_remote_login(false), + zero_remote_guild_card(false), + ep3_infinite_meseta(false), + red_name(false), + blank_name(false), + function_call_return_value(-1) {} Client::Client( struct bufferevent* bev, GameVersion version, ServerBehavior server_behavior) - : id(next_id++), - log("", client_log.min_level), - bb_game_state(0), - flags(flags_for_version(version, -1)), - channel(bev, version, nullptr, nullptr, this, string_printf("C-%" PRIX64, this->id), TerminalFormat::FG_YELLOW, TerminalFormat::FG_GREEN), - server_behavior(server_behavior), - should_disconnect(false), - should_send_to_lobby_server(false), - should_send_to_proxy_server(false), - proxy_destination_address(0), - proxy_destination_port(0), - x(0.0f), - z(0.0f), - area(0), - lobby_id(0), - lobby_client_id(0), - lobby_arrow_color(0), - preferred_lobby_id(-1), - save_game_data_event( - event_new( - bufferevent_get_base(bev), -1, EV_TIMEOUT | EV_PERSIST, - &Client::dispatch_save_game_data, this), - event_free), - card_battle_table_number(-1), - card_battle_table_seat_number(0), - card_battle_table_seat_state(0), - next_exp_value(0), - can_chat(true), - pending_bb_save_player_index(0), - dol_base_addr(0) { + : id(next_id++), + log("", client_log.min_level), + bb_game_state(0), + flags(flags_for_version(version, -1)), + channel(bev, version, nullptr, nullptr, this, string_printf("C-%" PRIX64, this->id), TerminalFormat::FG_YELLOW, TerminalFormat::FG_GREEN), + server_behavior(server_behavior), + should_disconnect(false), + should_send_to_lobby_server(false), + should_send_to_proxy_server(false), + proxy_destination_address(0), + proxy_destination_port(0), + x(0.0f), + z(0.0f), + area(0), + lobby_id(0), + lobby_client_id(0), + lobby_arrow_color(0), + preferred_lobby_id(-1), + save_game_data_event( + event_new( + bufferevent_get_base(bev), -1, EV_TIMEOUT | EV_PERSIST, + &Client::dispatch_save_game_data, this), + event_free), + card_battle_table_number(-1), + card_battle_table_seat_number(0), + card_battle_table_seat_state(0), + next_exp_value(0), + can_chat(true), + pending_bb_save_player_index(0), + dol_base_addr(0) { this->last_switch_enabled_command.header.subcommand = 0; memset(&this->next_connection_addr, 0, sizeof(this->next_connection_addr)); @@ -141,8 +134,6 @@ void Client::import_config(const ClientConfigBB& cc) { this->game_data.bb_player_index = cc.bb_player_index; } - - void Client::dispatch_save_game_data(evutil_socket_t, short, void* ctx) { reinterpret_cast(ctx)->save_game_data(); } diff --git a/src/Client.hh b/src/Client.hh index c21bdbde..d07cc413 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -6,23 +6,18 @@ #include "Channel.hh" #include "CommandFormats.hh" +#include "Episode3/BattleRecord.hh" +#include "Episode3/Tournament.hh" #include "FileContentsCache.hh" #include "FunctionCompiler.hh" #include "License.hh" -#include "PatchFileIndex.hh" -#include "Player.hh" #include "PSOEncryption.hh" #include "PSOProtocol.hh" +#include "PatchFileIndex.hh" +#include "Player.hh" #include "Text.hh" -#include "Episode3/BattleRecord.hh" -#include "Episode3/Tournament.hh" - - extern const uint64_t CLIENT_CONFIG_MAGIC; -extern FileContentsCache client_options_cache; - - struct ClientOptions { // Options used on both game and proxy server @@ -61,45 +56,45 @@ struct Client { // Note that this flag is NOT set for Episode 3 Trial Edition clients, since // that version is similar enough to the release version of Episode 3 that // newserv does not have to change its behavior at all. - IS_TRIAL_EDITION = 0x00002000, + IS_TRIAL_EDITION = 0x00002000, // Client is DC v1 - IS_DC_V1 = 0x00000010, + IS_DC_V1 = 0x00000010, // For patch server clients, client is Blue Burst rather than PC - IS_BB_PATCH = 0x00000001, + IS_BB_PATCH = 0x00000001, // After joining a lobby, client will no longer send D6 commands when they // close message boxes - NO_D6_AFTER_LOBBY = 0x00000002, + NO_D6_AFTER_LOBBY = 0x00000002, // Client has the above flag and has already joined a lobby, or is not GC - NO_D6 = 0x00000004, + NO_D6 = 0x00000004, // Client is Episode 3, should be able to see CARD lobbies, and should only // be able to see/join games with the EPISODE_3_ONLY flag - IS_EPISODE_3 = 0x00000008, + IS_EPISODE_3 = 0x00000008, // Client disconnects if it receives B2 (send_function_call) - NO_SEND_FUNCTION_CALL = 0x00000200, + NO_SEND_FUNCTION_CALL = 0x00000200, // Client requires doubly-encrypted code section in send_function_call - ENCRYPTED_SEND_FUNCTION_CALL = 0x00000800, + ENCRYPTED_SEND_FUNCTION_CALL = 0x00000800, // Client supports send_function_call but does not actually run the code - SEND_FUNCTION_CALL_CHECKSUM_ONLY = 0x00001000, + SEND_FUNCTION_CALL_CHECKSUM_ONLY = 0x00001000, // Client is vulnerable to a buffer overflow that we can use to enable // send_function_call USE_OVERFLOW_FOR_SEND_FUNCTION_CALL = 0x00008000, // Client is loading into a game - LOADING = 0x00000020, + LOADING = 0x00000020, // Client is loading a quest - LOADING_QUEST = 0x00000040, + LOADING_QUEST = 0x00000040, // Client is waiting to join an Episode 3 card auction - AWAITING_CARD_AUCTION = 0x00010000, + AWAITING_CARD_AUCTION = 0x00010000, // Client is in the information menu (login server only) - IN_INFORMATION_MENU = 0x00000080, + IN_INFORMATION_MENU = 0x00000080, // Client is at the welcome message (login server only) - AT_WELCOME_MESSAGE = 0x00000100, + AT_WELCOME_MESSAGE = 0x00000100, // Client has already received a 97 (enable saves) command, so don't show // the programs menu anymore - SAVE_ENABLED = 0x00000400, + SAVE_ENABLED = 0x00000400, // Client has received newserv's Episode 3 card definitions, so don't send // them again - HAS_EP3_CARD_DEFS = 0x00004000, + HAS_EP3_CARD_DEFS = 0x00004000, }; uint64_t id; @@ -138,7 +133,7 @@ struct Client { uint8_t lobby_arrow_color; // lobby arrow color ID int64_t preferred_lobby_id; // <0 = no preference ClientGameData game_data; - std::unique_ptr save_game_data_event; + std::unique_ptr save_game_data_event; int16_t card_battle_table_number; uint16_t card_battle_table_seat_number; uint16_t card_battle_table_seat_state; diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index b47ed435..5d9142da 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1,17 +1,17 @@ #pragma once -#include -#include -#include #include +#include +#include +#include -#include "PSOProtocol.hh" -#include "Text.hh" -#include "Player.hh" #include "Episode3/DataIndex.hh" #include "Episode3/DeckState.hh" #include "Episode3/MapState.hh" #include "Episode3/PlayerStateSubordinates.hh" +#include "PSOProtocol.hh" +#include "Player.hh" +#include "Text.hh" #define __packed__ __attribute__((packed)) @@ -45,8 +45,6 @@ // Structures are sorted by command number. Long BB commands are placed in order // according to their low byte; for example, command 01EB is in position as EB. - - // Text escape codes // Most text fields allow the use of various escape codes to change decoding, @@ -85,8 +83,6 @@ // - - $r: Right arrow // - - $u: Up arrow - - // This is the format of newserv's security data, which we call the client // config. This data is opaque to the client, so this structure is not // technically part of the PSO protocol. Because it is opaque to the client, we @@ -124,8 +120,6 @@ struct ClientConfigBB { parray unused; } __packed__; - - // Patch server commands // The patch protocol is identical between PSO PC and PSO BB (the only versions @@ -309,7 +303,8 @@ struct S_Reconnect { le_uint16_t unused = 0; } __packed__; -struct S_Reconnect_Patch_14 : S_Reconnect { } __packed__; +struct S_Reconnect_Patch_14 : S_Reconnect { +} __packed__; // 15 (S->C): Login failure // No arguments @@ -318,8 +313,6 @@ struct S_Reconnect_Patch_14 : S_Reconnect { } __packed__; // No commands beyond 15 are valid on the patch server. - - // Game server commands // 00: Invalid command @@ -482,8 +475,10 @@ struct S_UpdateClientConfig { ClientConfigT cfg; } __packed__; -struct S_UpdateClientConfig_DC_PC_V3_04 : S_UpdateClientConfig { } __packed__; -struct S_UpdateClientConfig_BB_04 : S_UpdateClientConfig { } __packed__; +struct S_UpdateClientConfig_DC_PC_V3_04 : S_UpdateClientConfig { +} __packed__; +struct S_UpdateClientConfig_BB_04 : S_UpdateClientConfig { +} __packed__; // 05: Disconnect // No arguments @@ -534,8 +529,10 @@ struct S_MenuEntry { le_uint16_t flags = 0x0F04; // Should be this value, apparently ptext text; } __packed__; -struct S_MenuEntry_PC_BB_07_1F : S_MenuEntry { } __packed__; -struct S_MenuEntry_DC_V3_07_1F : S_MenuEntry { } __packed__; +struct S_MenuEntry_PC_BB_07_1F : S_MenuEntry { +} __packed__; +struct S_MenuEntry_DC_V3_07_1F : S_MenuEntry { +} __packed__; // 08 (C->S): Request game list // No arguments @@ -569,8 +566,10 @@ struct S_GameMenuEntry { // 20 = Is challenge mode uint8_t flags = 0; } __packed__; -struct S_GameMenuEntry_PC_BB_08 : S_GameMenuEntry { } __packed__; -struct S_GameMenuEntry_DC_V3_08_Ep3_E6 : S_GameMenuEntry { } __packed__; +struct S_GameMenuEntry_PC_BB_08 : S_GameMenuEntry { +} __packed__; +struct S_GameMenuEntry_DC_V3_08_Ep3_E6 : S_GameMenuEntry { +} __packed__; // 09 (C->S): Menu item info request // Server will respond with an 11 command, or an A3 or A5 if the specified menu @@ -660,16 +659,20 @@ struct C_MenuSelection_10_Flag01 { C_MenuSelection_10_Flag00 basic_cmd; ptext unknown_a1; } __packed__; -struct C_MenuSelection_DC_V3_10_Flag01 : C_MenuSelection_10_Flag01 { } __packed__; -struct C_MenuSelection_PC_BB_10_Flag01 : C_MenuSelection_10_Flag01 { } __packed__; +struct C_MenuSelection_DC_V3_10_Flag01 : C_MenuSelection_10_Flag01 { +} __packed__; +struct C_MenuSelection_PC_BB_10_Flag01 : C_MenuSelection_10_Flag01 { +} __packed__; template struct C_MenuSelection_10_Flag02 { C_MenuSelection_10_Flag00 basic_cmd; ptext password; } __packed__; -struct C_MenuSelection_DC_V3_10_Flag02 : C_MenuSelection_10_Flag02 { } __packed__; -struct C_MenuSelection_PC_BB_10_Flag02 : C_MenuSelection_10_Flag02 { } __packed__; +struct C_MenuSelection_DC_V3_10_Flag02 : C_MenuSelection_10_Flag02 { +} __packed__; +struct C_MenuSelection_PC_BB_10_Flag02 : C_MenuSelection_10_Flag02 { +} __packed__; template struct C_MenuSelection_10_Flag03 { @@ -677,8 +680,10 @@ struct C_MenuSelection_10_Flag03 { ptext unknown_a1; ptext password; } __packed__; -struct C_MenuSelection_DC_V3_10_Flag03 : C_MenuSelection_10_Flag03 { } __packed__; -struct C_MenuSelection_PC_BB_10_Flag03 : C_MenuSelection_10_Flag03 { } __packed__; +struct C_MenuSelection_DC_V3_10_Flag03 : C_MenuSelection_10_Flag03 { +} __packed__; +struct C_MenuSelection_PC_BB_10_Flag03 : C_MenuSelection_10_Flag03 { +} __packed__; // 11 (S->C): Ship info // Same format as 01 command. The text appears in a small box in the lower-left @@ -748,7 +753,8 @@ struct C_WriteFileConfirmation_V3_BB_13_A7 { // Note: PSO XB seems to ignore the address field, which makes sense given its // networking architecture. -struct S_Reconnect_19 : S_Reconnect { } __packed__; +struct S_Reconnect_19 : S_Reconnect { +} __packed__; // Because PSO PC and some versions of PSO DC/GC use the same port but different // protocols, we use a specially-crafted 19 command to send them to two @@ -915,11 +921,14 @@ struct S_GuildCardSearchResult { SC_MeetUserExtension extension; } __packed__; struct S_GuildCardSearchResult_PC_41 - : S_GuildCardSearchResult { } __packed__; + : S_GuildCardSearchResult { +} __packed__; struct S_GuildCardSearchResult_DC_V3_41 - : S_GuildCardSearchResult { } __packed__; + : S_GuildCardSearchResult { +} __packed__; struct S_GuildCardSearchResult_BB_41 - : S_GuildCardSearchResult { } __packed__; + : S_GuildCardSearchResult { +} __packed__; // 42: Invalid command // 43: Invalid command @@ -1084,8 +1093,10 @@ struct S_JoinGame { uint8_t unused3 = 0; } __packed__; -struct S_JoinGame_PC_64 : S_JoinGame { } __packed__; -struct S_JoinGame_DC_GC_64 : S_JoinGame { } __packed__; +struct S_JoinGame_PC_64 : S_JoinGame { +} __packed__; +struct S_JoinGame_DC_GC_64 : S_JoinGame { +} __packed__; struct S_JoinGame_GC_Ep3_64 : S_JoinGame_DC_GC_64 { // This field is only present if the game (and client) is Episode 3. Similarly @@ -1101,7 +1112,8 @@ struct S_JoinGame_XB_64 : S_JoinGame { parray unknown_a1; } __packed__; -struct S_JoinGame_BB_64 : S_JoinGame { } __packed__; +struct S_JoinGame_BB_64 : S_JoinGame { +} __packed__; // 65 (S->C): Add player to game // When a player joins an existing game, the joining player receives a 64 @@ -1134,11 +1146,14 @@ struct S_JoinLobby { } } __packed__; struct S_JoinLobby_PC_65_67_68 - : S_JoinLobby { } __packed__; + : S_JoinLobby { +} __packed__; struct S_JoinLobby_DC_GC_65_67_68_Ep3_EB - : S_JoinLobby { } __packed__; + : S_JoinLobby { +} __packed__; struct S_JoinLobby_BB_65_67_68 - : S_JoinLobby { } __packed__; + : S_JoinLobby { +} __packed__; struct S_JoinLobby_XB_65_67_68 { uint8_t client_id = 0; @@ -1161,8 +1176,7 @@ struct S_JoinLobby_XB_65_67_68 { parray entries; static inline size_t size(size_t used_entries) { - return offsetof(S_JoinLobby_XB_65_67_68, entries) - + used_entries * sizeof(Entry); + return offsetof(S_JoinLobby_XB_65_67_68, entries) + used_entries * sizeof(Entry); } } __packed__; @@ -1267,8 +1281,10 @@ struct SC_SimpleMail_81 { ptext text; } __packed__; -struct SC_SimpleMail_PC_81 : SC_SimpleMail_81 { } __packed__; -struct SC_SimpleMail_DC_V3_81 : SC_SimpleMail_81 { } __packed__; +struct SC_SimpleMail_PC_81 : SC_SimpleMail_81 { +} __packed__; +struct SC_SimpleMail_DC_V3_81 : SC_SimpleMail_81 { +} __packed__; struct SC_SimpleMail_BB_81 { le_uint32_t player_tag = 0x00010000; @@ -1694,7 +1710,7 @@ struct C_Login_GC_9E : C_Login_DC_PC_GC_9D { union ClientConfigFields { ClientConfig cfg; parray data; - ClientConfigFields() : data() { } + ClientConfigFields() : data() {} } __packed__ client_config; } __packed__; struct C_LoginExtended_GC_9E : C_Login_GC_9E { @@ -1774,10 +1790,14 @@ struct S_QuestMenuEntry { ptext name; ptext short_description; } __packed__; -struct S_QuestMenuEntry_PC_A2_A4 : S_QuestMenuEntry { } __packed__; -struct S_QuestMenuEntry_DC_GC_A2_A4 : S_QuestMenuEntry { } __packed__; -struct S_QuestMenuEntry_XB_A2_A4 : S_QuestMenuEntry { } __packed__; -struct S_QuestMenuEntry_BB_A2_A4 : S_QuestMenuEntry { } __packed__; +struct S_QuestMenuEntry_PC_A2_A4 : S_QuestMenuEntry { +} __packed__; +struct S_QuestMenuEntry_DC_GC_A2_A4 : S_QuestMenuEntry { +} __packed__; +struct S_QuestMenuEntry_XB_A2_A4 : S_QuestMenuEntry { +} __packed__; +struct S_QuestMenuEntry_BB_A2_A4 : S_QuestMenuEntry { +} __packed__; // A3 (S->C): Quest information // Same format as 1A/D5 command (plain text) @@ -1948,8 +1968,10 @@ struct S_ExecuteCode_Footer_B2 { parray unused2; } __packed__; -struct S_ExecuteCode_Footer_GC_B2 : S_ExecuteCode_Footer_B2 { } __packed__; -struct S_ExecuteCode_Footer_DC_PC_XB_BB_B2 : S_ExecuteCode_Footer_B2 { } __packed__; +struct S_ExecuteCode_Footer_GC_B2 : S_ExecuteCode_Footer_B2 { +} __packed__; +struct S_ExecuteCode_Footer_DC_PC_XB_BB_B2 : S_ExecuteCode_Footer_B2 { +} __packed__; // B3 (C->S): Execute code and/or checksum memory result // Not used on versions that don't support the B2 command (see above). @@ -2138,9 +2160,12 @@ struct S_ChoiceSearchEntry { ItemIDT category_id = 0; ptext text; } __packed__; -struct S_ChoiceSearchEntry_DC_C0 : S_ChoiceSearchEntry { } __packed__; -struct S_ChoiceSearchEntry_V3_C0 : S_ChoiceSearchEntry { } __packed__; -struct S_ChoiceSearchEntry_PC_BB_C0 : S_ChoiceSearchEntry { } __packed__; +struct S_ChoiceSearchEntry_DC_C0 : S_ChoiceSearchEntry { +} __packed__; +struct S_ChoiceSearchEntry_V3_C0 : S_ChoiceSearchEntry { +} __packed__; +struct S_ChoiceSearchEntry_PC_BB_C0 : S_ChoiceSearchEntry { +} __packed__; // Top-level categories are things like "Level", "Class", etc. // Choices for each top-level category immediately follow the category, so @@ -2175,8 +2200,10 @@ struct C_CreateGame { // players; if set to 1, it's v2-only. uint8_t episode = 0; // 1-4 on V3+ (3 on Episode 3); unused on DC/PC } __packed__; -struct C_CreateGame_DC_V3_0C_C1_Ep3_EC : C_CreateGame { } __packed__; -struct C_CreateGame_PC_C1 : C_CreateGame { } __packed__; +struct C_CreateGame_DC_V3_0C_C1_Ep3_EC : C_CreateGame { +} __packed__; +struct C_CreateGame_PC_C1 : C_CreateGame { +} __packed__; struct C_CreateGame_BB_C1 : C_CreateGame { uint8_t solo_mode = 0; @@ -2187,8 +2214,10 @@ struct C_CreateGame_BB_C1 : C_CreateGame { // Server does not respond. // The ChoiceSearchConfig structure is defined in Player.hh. -struct C_ChoiceSearchSelections_DC_C2_C3 : ChoiceSearchConfig { } __packed__; -struct C_ChoiceSearchSelections_PC_V3_BB_C2_C3 : ChoiceSearchConfig { } __packed__; +struct C_ChoiceSearchSelections_DC_C2_C3 : ChoiceSearchConfig { +} __packed__; +struct C_ChoiceSearchSelections_PC_V3_BB_C2_C3 : ChoiceSearchConfig { +} __packed__; // C3 (C->S): Execute choice search (DCv2 and later versions) // Same format as C2. The disabled field is unused. @@ -2235,8 +2264,10 @@ struct C_SetBlockedSenders_C6 { parray blocked_senders; } __packed__; -struct C_SetBlockedSenders_V3_C6 : C_SetBlockedSenders_C6<30> { } __packed__; -struct C_SetBlockedSenders_BB_C6 : C_SetBlockedSenders_C6<28> { } __packed__; +struct C_SetBlockedSenders_V3_C6 : C_SetBlockedSenders_C6<30> { +} __packed__; +struct C_SetBlockedSenders_BB_C6 : C_SetBlockedSenders_C6<28> { +} __packed__; // C7 (C->S): Enable simple mail auto-reply (V3/BB) // Same format as 1A/D5 command (plain text). @@ -2402,8 +2433,10 @@ struct S_InfoBoardEntry_D8 { ptext name; ptext message; } __packed__; -struct S_InfoBoardEntry_BB_D8 : S_InfoBoardEntry_D8 { } __packed__; -struct S_InfoBoardEntry_V3_D8 : S_InfoBoardEntry_D8 { } __packed__; +struct S_InfoBoardEntry_BB_D8 : S_InfoBoardEntry_D8 { +} __packed__; +struct S_InfoBoardEntry_V3_D8 : S_InfoBoardEntry_D8 { +} __packed__; // D9 (C->S): Write info board (V3/BB) // Contents are plain text, like 1A/D5. @@ -3187,8 +3220,6 @@ struct S_SetShutdownCommand_BB_01EF { // FE: Invalid command // FF: Invalid command - - // Now, the game subcommands (used in commands 60, 62, 6C, 6D, C9, and CB). // These are laid out similarly as above. These structs start with G_ to // indicate that they are (usually) bidirectional, and are (usually) generated @@ -3212,8 +3243,6 @@ struct S_SetShutdownCommand_BB_01EF { // commands must be used. The 60 and 62 commands exhibit undefined behavior if // this limit is exceeded. - - // These common structures are used my many subcommands. struct G_ClientIDHeader { uint8_t subcommand = 0; @@ -3242,8 +3271,6 @@ struct G_ExtendedHeader { le_uint32_t size = 0; } __packed__; - - // 6x00: Invalid subcommand // 6x01: Invalid subcommand @@ -3295,8 +3322,10 @@ struct G_SendGuildCard_DC_PC_V3 { struct G_SendGuildCard_DC_6x06 : G_SendGuildCard_DC_PC_V3 { parray unused3; } __packed__; -struct G_SendGuildCard_PC_6x06 : G_SendGuildCard_DC_PC_V3 { } __packed__; -struct G_SendGuildCard_V3_6x06 : G_SendGuildCard_DC_PC_V3 { } __packed__; +struct G_SendGuildCard_PC_6x06 : G_SendGuildCard_DC_PC_V3 { +} __packed__; +struct G_SendGuildCard_V3_6x06 : G_SendGuildCard_DC_PC_V3 { +} __packed__; struct G_SendGuildCard_BB_6x06 { G_UnusedHeader header; @@ -5052,8 +5081,6 @@ struct G_EnemyKilled_6xC8 { // 6xFE: Invalid subcommand // 6xFF: Invalid subcommand - - // Now, the Episode 3 CARD battle subsubcommands (used in commands 6xB3, 6xB4, // and 6xB5). Note that even though there's no overlap in the subsubcommand // number space, the various subsubcommands must be used with the correct 6xBx diff --git a/src/CommonItemSet.cc b/src/CommonItemSet.cc index b73762be..90fe8a29 100644 --- a/src/CommonItemSet.cc +++ b/src/CommonItemSet.cc @@ -2,15 +2,14 @@ #include "StaticGameData.hh" - - CommonItemSet::CommonItemSet(shared_ptr data) - : gsl(data, true) { } + : gsl(data, true) {} const CommonItemSet::Table& CommonItemSet::get_table( Episode episode, GameMode mode, uint8_t difficulty, uint8_t secid) const { // TODO: What should we do for Ep4? - string filename = string_printf("ItemPT%s%s%c%1d.rel", + string filename = string_printf( + "ItemPT%s%s%c%1d.rel", ((mode == GameMode::CHALLENGE) ? "c" : ""), ((episode == Episode::EP2) ? "l" : ""), tolower(abbreviation_for_difficulty(difficulty)), @@ -24,15 +23,12 @@ const CommonItemSet::Table& CommonItemSet::get_table( return *reinterpret_cast*>(data.first); } - - RELFileSet::RELFileSet(std::shared_ptr data) - : data(data), r(*this->data) { } - - + : data(data), + r(*this->data) {} ArmorRandomSet::ArmorRandomSet(std::shared_ptr data) - : RELFileSet(data) { + : RELFileSet(data) { // For some reason the footer tables are doubly indirect in this file uint32_t specs_offset_offset = r.pget_u32b(data->size() - 0x10); uint32_t specs_offset = r.pget_u32b(specs_offset_offset); @@ -54,15 +50,14 @@ ArmorRandomSet::get_unit_table(size_t index) const { return this->get_table(this->tables->at(2), index); } - - ToolRandomSet::ToolRandomSet(std::shared_ptr data) - : RELFileSet(data) { + : RELFileSet(data) { uint32_t specs_offset = r.pget_u32b(data->size() - 0x10); this->common_recovery_table_spec = &r.pget(r.pget_u32b( specs_offset)); - this->rare_recovery_table_spec = &r.pget(r.pget_u32b( - specs_offset + sizeof(uint32_t)), 2 * sizeof(TableSpec)); + this->rare_recovery_table_spec = &r.pget( + r.pget_u32b(specs_offset + sizeof(uint32_t)), + 2 * sizeof(TableSpec)); this->tech_disk_table_spec = this->rare_recovery_table_spec + 1; this->tech_disk_level_table_spec = &r.pget(r.pget_u32b( specs_offset + 2 * sizeof(uint32_t))); @@ -88,10 +83,8 @@ ToolRandomSet::get_tech_disk_level_table(size_t index) const { return this->get_table(*this->tech_disk_level_table_spec, index); } - - WeaponRandomSet::WeaponRandomSet(std::shared_ptr data) - : RELFileSet(data) { + : RELFileSet(data) { uint32_t offsets_offset = this->r.pget_u32b(data->size() - 0x10); this->offsets = &this->r.pget(offsets_offset); } @@ -107,16 +100,14 @@ WeaponRandomSet::get_weapon_type_table(size_t index) const { const parray* WeaponRandomSet::get_bonus_type_table(size_t which, size_t index) const { - uint32_t base_offset = which - ? this->offsets->bonus_type_table2 : this->offsets->bonus_type_table1; + uint32_t base_offset = which ? this->offsets->bonus_type_table2 : this->offsets->bonus_type_table1; return &this->r.pget>( base_offset + sizeof(parray) * index); } const WeaponRandomSet::RangeTableEntry* WeaponRandomSet::get_bonus_range(size_t which, size_t index) const { - uint32_t base_offset = which - ? this->offsets->bonus_range_table2 : this->offsets->bonus_range_table1; + uint32_t base_offset = which ? this->offsets->bonus_range_table2 : this->offsets->bonus_range_table1; return &this->r.pget( base_offset + sizeof(RangeTableEntry) * index); } diff --git a/src/CommonItemSet.hh b/src/CommonItemSet.hh index 3db53edf..dcb92bc2 100644 --- a/src/CommonItemSet.hh +++ b/src/CommonItemSet.hh @@ -6,7 +6,6 @@ #include "StaticGameData.hh" #include "Text.hh" - class CommonItemSet { public: template @@ -248,8 +247,6 @@ private: GSLArchive gsl; }; - - class RELFileSet { public: template diff --git a/src/Compression.cc b/src/Compression.cc index 38dd813d..d5bf3c02 100644 --- a/src/Compression.cc +++ b/src/Compression.cc @@ -1,9 +1,9 @@ #include "Compression.hh" #include -#include #include #include +#include #include #include @@ -12,16 +12,14 @@ using namespace std; - - PRSCompressor::PRSCompressor(function progress_fn) - : progress_fn(progress_fn), - closed(false), - control_byte_offset(0), - pending_control_bits(0), - input_bytes(0), - compression_offset(0), - reverse_log_index(0x100) { + : progress_fn(progress_fn), + closed(false), + control_byte_offset(0), + pending_control_bits(0), + input_bytes(0), + compression_offset(0), + reverse_log_index(0x100) { this->output.put_u8(0); } @@ -65,8 +63,8 @@ void PRSCompressor::advance() { size_t match_size = 0; size_t match_loop_bytes = this->compression_offset - match_offset; while ((match_size < 0x100) && - (this->compression_offset + match_size < this->input_bytes) && - (this->reverse_log[(match_offset + (match_size % match_loop_bytes)) & 0x1FFF] == this->forward_log[(this->compression_offset + match_size) & 0xFF])) { + (this->compression_offset + match_size < this->input_bytes) && + (this->reverse_log[(match_offset + (match_size % match_loop_bytes)) & 0x1FFF] == this->forward_log[(this->compression_offset + match_size) & 0xFF])) { match_size++; } @@ -204,8 +202,6 @@ void PRSCompressor::flush_control() { } } - - string prs_compress( const void* vdata, size_t size, function progress_fn) { PRSCompressor prs(progress_fn); @@ -218,11 +214,10 @@ string prs_compress( return prs_compress(data.data(), data.size(), progress_fn); } - - class ControlStreamReader { public: - ControlStreamReader(StringReader& r) : r(r), bits(0x0000) { } + ControlStreamReader(StringReader& r) : r(r), + bits(0x0000) {} bool read() { if (!(this->bits & 0x0100)) { @@ -306,7 +301,7 @@ string prs_decompress(const void* data, size_t size, size_t max_output_size) { // from another byte in the data stream) count = (a & 7) ? ((a & 7) + 2) : (r.get_u8() + 1); - // Control 00 = short backreference + // Control 00 = short backreference } else { // Count comes from 2 bits in the control stream instead of from the // data stream (and 2 is added). Importantly, the control stream bits @@ -388,8 +383,6 @@ size_t prs_decompress_size(const string& data, size_t max_output_size) { return prs_decompress_size(data.data(), data.size(), max_output_size); } - - void prs_disassemble(FILE* stream, const void* data, size_t size) { size_t output_bytes = 0; StringReader r(data, size); @@ -439,8 +432,6 @@ void prs_disassemble(FILE* stream, const std::string& data) { return prs_disassemble(stream, data.data(), data.size()); } - - // BC0 is a compression algorithm fairly similar to PRS, but with a simpler set // of commands. Like PRS, there is a control stream, indicating when to copy a // literal byte from the input and when to copy from a backreference; unlike @@ -637,8 +628,8 @@ string bc0_decompress(const string& data) { memo_offset = (memo_offset + 1) & 0x0FFF; } - // Control bit 1 means to write a byte directly from the input to the - // output. As above, the byte is also written to the memo. + // Control bit 1 means to write a byte directly from the input to the + // output. As above, the byte is also written to the memo. } else { uint8_t v = r.get_u8(); w.put_u8(v); diff --git a/src/Compression.hh b/src/Compression.hh index ee3acf43..762832e9 100644 --- a/src/Compression.hh +++ b/src/Compression.hh @@ -2,14 +2,12 @@ #include -#include -#include #include +#include +#include #include "Text.hh" - - // Use this class if you need to compress from multiple input buffers, or need // to compress multiple chunks and don't want to copy their contents // unnecessarily. (For most common use cases, use prs_compress (below) instead.) diff --git a/src/DNSServer.cc b/src/DNSServer.cc index 25aacb57..d680fbdc 100644 --- a/src/DNSServer.cc +++ b/src/DNSServer.cc @@ -1,28 +1,28 @@ #include "DNSServer.hh" +#include +#include #include #include #include -#include -#include #include #include #include -#include #include +#include #include "Loggers.hh" #include "NetworkAddresses.hh" using namespace std; - - -DNSServer::DNSServer(shared_ptr base, - uint32_t local_connect_address, uint32_t external_connect_address) : - base(base), local_connect_address(local_connect_address), - external_connect_address(external_connect_address) { } +DNSServer::DNSServer( + shared_ptr base, + uint32_t local_connect_address, uint32_t external_connect_address) + : base(base), + local_connect_address(local_connect_address), + external_connect_address(external_connect_address) {} DNSServer::~DNSServer() { for (const auto& it : this->fd_to_receive_event) { @@ -43,9 +43,9 @@ void DNSServer::listen(int port) { } void DNSServer::add_socket(int fd) { - unique_ptr e(event_new(this->base.get(), - fd, EV_READ | EV_PERSIST, &DNSServer::dispatch_on_receive_message, - this), event_free); + unique_ptr e( + event_new(this->base.get(), fd, EV_READ | EV_PERSIST, &DNSServer::dispatch_on_receive_message, this), + event_free); event_add(e.get(), nullptr); this->fd_to_receive_event.emplace(fd, move(e)); } diff --git a/src/DNSServer.hh b/src/DNSServer.hh index d9f79ea9..a58b5719 100644 --- a/src/DNSServer.hh +++ b/src/DNSServer.hh @@ -3,10 +3,9 @@ #include #include -#include -#include #include - +#include +#include class DNSServer { public: @@ -28,7 +27,7 @@ public: private: std::shared_ptr base; - std::unordered_map> fd_to_receive_event; + std::unordered_map> fd_to_receive_event; uint32_t local_connect_address; uint32_t external_connect_address; diff --git a/src/Episode3/AssistServer.cc b/src/Episode3/AssistServer.cc index e05303a4..89ef97ac 100644 --- a/src/Episode3/AssistServer.cc +++ b/src/Episode3/AssistServer.cc @@ -6,8 +6,6 @@ using namespace std; namespace Episode3 { - - // Note: This order matches the order that the cards are defined in the original // code. This is relevant for consistency of results when choosing a random card // (for God Whim). @@ -24,81 +22,81 @@ const vector ALL_ASSIST_CARD_IDS = { AssistEffect assist_effect_number_for_card_id(uint16_t card_id) { static const unordered_map card_id_to_effect({ - {0x00F5, /* 0x0001 */ AssistEffect::DICE_HALF}, - {0x00F6, /* 0x0002 */ AssistEffect::DICE_PLUS_1}, - {0x00F7, /* 0x0003 */ AssistEffect::DICE_FEVER}, - {0x00F8, /* 0x0004 */ AssistEffect::CARD_RETURN}, - {0x00F9, /* 0x0005 */ AssistEffect::LAND_PRICE}, - {0x00FA, /* 0x0006 */ AssistEffect::POWERLESS_RAIN}, - {0x00FB, /* 0x0007 */ AssistEffect::BRAVE_WIND}, - {0x00FC, /* 0x0008 */ AssistEffect::SILENT_COLOSSEUM}, - {0x00FD, /* 0x0009 */ AssistEffect::RESISTANCE}, - {0x00FE, /* 0x000A */ AssistEffect::INDEPENDENT}, - {0x00FF, /* 0x000B */ AssistEffect::ASSISTLESS}, - {0x0100, /* 0x000C */ AssistEffect::ATK_DICE_2}, - {0x0101, /* 0x000D */ AssistEffect::DEFLATION}, - {0x0102, /* 0x000E */ AssistEffect::INFLATION}, - {0x0103, /* 0x000F */ AssistEffect::EXCHANGE}, - {0x0104, /* 0x0010 */ AssistEffect::INFLUENCE}, - {0x0105, /* 0x0011 */ AssistEffect::SKIP_SET}, - {0x0106, /* 0x0012 */ AssistEffect::SKIP_MOVE}, - {0x0121, /* 0x0013 */ AssistEffect::SKIP_ACT}, - {0x0137, /* 0x0014 */ AssistEffect::SKIP_DRAW}, - {0x0107, /* 0x0015 */ AssistEffect::FLY}, - {0x0108, /* 0x0016 */ AssistEffect::NECROMANCER}, - {0x0109, /* 0x0017 */ AssistEffect::PERMISSION}, - {0x010A, /* 0x0018 */ AssistEffect::SHUFFLE_ALL}, - {0x010B, /* 0x0019 */ AssistEffect::LEGACY}, - {0x010C, /* 0x001A */ AssistEffect::ASSIST_REVERSE}, - {0x010D, /* 0x001B */ AssistEffect::STAMINA}, - {0x010E, /* 0x001C */ AssistEffect::AP_ABSORPTION}, - {0x010F, /* 0x001D */ AssistEffect::HEAVY_FOG}, - {0x0125, /* 0x001E */ AssistEffect::TRASH_1}, - {0x0126, /* 0x001F */ AssistEffect::EMPTY_HAND}, - {0x0127, /* 0x0020 */ AssistEffect::HITMAN}, - {0x0128, /* 0x0021 */ AssistEffect::ASSIST_TRASH}, - {0x0129, /* 0x0022 */ AssistEffect::SHUFFLE_GROUP}, - {0x012A, /* 0x0023 */ AssistEffect::ASSIST_VANISH}, - {0x012B, /* 0x0024 */ AssistEffect::CHARITY}, - {0x012C, /* 0x0025 */ AssistEffect::INHERITANCE}, - {0x012D, /* 0x0026 */ AssistEffect::FIX}, - {0x012E, /* 0x0027 */ AssistEffect::MUSCULAR}, - {0x012F, /* 0x0028 */ AssistEffect::CHANGE_BODY}, - {0x0130, /* 0x0029 */ AssistEffect::GOD_WHIM}, - {0x0131, /* 0x002A */ AssistEffect::GOLD_RUSH}, - {0x0132, /* 0x002B */ AssistEffect::ASSIST_RETURN}, - {0x0133, /* 0x002C */ AssistEffect::REQUIEM}, - {0x0134, /* 0x002D */ AssistEffect::RANSOM}, - {0x0135, /* 0x002E */ AssistEffect::SIMPLE}, - {0x0136, /* 0x002F */ AssistEffect::SLOW_TIME}, - {0x023F, /* 0x0030 */ AssistEffect::QUICK_TIME}, - {0x0138, /* 0x0031 */ AssistEffect::TERRITORY}, - {0x0139, /* 0x0032 */ AssistEffect::OLD_TYPE}, - {0x013A, /* 0x0033 */ AssistEffect::FLATLAND}, - {0x013B, /* 0x0034 */ AssistEffect::IMMORTALITY}, - {0x013C, /* 0x0035 */ AssistEffect::SNAIL_PACE}, - {0x013D, /* 0x0036 */ AssistEffect::TECH_FIELD}, - {0x013E, /* 0x0037 */ AssistEffect::FOREST_RAIN}, - {0x013F, /* 0x0038 */ AssistEffect::CAVE_WIND}, - {0x0140, /* 0x0039 */ AssistEffect::MINE_BRIGHTNESS}, - {0x0141, /* 0x003A */ AssistEffect::RUIN_DARKNESS}, - {0x0142, /* 0x003B */ AssistEffect::SABER_DANCE}, - {0x0143, /* 0x003C */ AssistEffect::BULLET_STORM}, - {0x0144, /* 0x003D */ AssistEffect::CANE_PALACE}, - {0x0145, /* 0x003E */ AssistEffect::GIANT_GARDEN}, - {0x0146, /* 0x003F */ AssistEffect::MARCH_OF_THE_MEEK}, - {0x0148, /* 0x0040 */ AssistEffect::SUPPORT}, - {0x014A, /* 0x0041 */ AssistEffect::RICH}, - {0x014B, /* 0x0042 */ AssistEffect::REVERSE_CARD}, - {0x014C, /* 0x0043 */ AssistEffect::VENGEANCE}, - {0x014D, /* 0x0044 */ AssistEffect::SQUEEZE}, - {0x014E, /* 0x0045 */ AssistEffect::HOMESICK}, - {0x0240, /* 0x0046 */ AssistEffect::BOMB}, - {0x0241, /* 0x0047 */ AssistEffect::SKIP_TURN}, - {0x0242, /* 0x0048 */ AssistEffect::BATTLE_ROYALE}, - {0x0018, /* 0x0049 */ AssistEffect::DICE_FEVER_PLUS}, - {0x0019, /* 0x004A */ AssistEffect::RICH_PLUS}, - {0x001A, /* 0x004B */ AssistEffect::CHARITY_PLUS}, + {0x00F5, /* 0x0001 */ AssistEffect::DICE_HALF}, + {0x00F6, /* 0x0002 */ AssistEffect::DICE_PLUS_1}, + {0x00F7, /* 0x0003 */ AssistEffect::DICE_FEVER}, + {0x00F8, /* 0x0004 */ AssistEffect::CARD_RETURN}, + {0x00F9, /* 0x0005 */ AssistEffect::LAND_PRICE}, + {0x00FA, /* 0x0006 */ AssistEffect::POWERLESS_RAIN}, + {0x00FB, /* 0x0007 */ AssistEffect::BRAVE_WIND}, + {0x00FC, /* 0x0008 */ AssistEffect::SILENT_COLOSSEUM}, + {0x00FD, /* 0x0009 */ AssistEffect::RESISTANCE}, + {0x00FE, /* 0x000A */ AssistEffect::INDEPENDENT}, + {0x00FF, /* 0x000B */ AssistEffect::ASSISTLESS}, + {0x0100, /* 0x000C */ AssistEffect::ATK_DICE_2}, + {0x0101, /* 0x000D */ AssistEffect::DEFLATION}, + {0x0102, /* 0x000E */ AssistEffect::INFLATION}, + {0x0103, /* 0x000F */ AssistEffect::EXCHANGE}, + {0x0104, /* 0x0010 */ AssistEffect::INFLUENCE}, + {0x0105, /* 0x0011 */ AssistEffect::SKIP_SET}, + {0x0106, /* 0x0012 */ AssistEffect::SKIP_MOVE}, + {0x0121, /* 0x0013 */ AssistEffect::SKIP_ACT}, + {0x0137, /* 0x0014 */ AssistEffect::SKIP_DRAW}, + {0x0107, /* 0x0015 */ AssistEffect::FLY}, + {0x0108, /* 0x0016 */ AssistEffect::NECROMANCER}, + {0x0109, /* 0x0017 */ AssistEffect::PERMISSION}, + {0x010A, /* 0x0018 */ AssistEffect::SHUFFLE_ALL}, + {0x010B, /* 0x0019 */ AssistEffect::LEGACY}, + {0x010C, /* 0x001A */ AssistEffect::ASSIST_REVERSE}, + {0x010D, /* 0x001B */ AssistEffect::STAMINA}, + {0x010E, /* 0x001C */ AssistEffect::AP_ABSORPTION}, + {0x010F, /* 0x001D */ AssistEffect::HEAVY_FOG}, + {0x0125, /* 0x001E */ AssistEffect::TRASH_1}, + {0x0126, /* 0x001F */ AssistEffect::EMPTY_HAND}, + {0x0127, /* 0x0020 */ AssistEffect::HITMAN}, + {0x0128, /* 0x0021 */ AssistEffect::ASSIST_TRASH}, + {0x0129, /* 0x0022 */ AssistEffect::SHUFFLE_GROUP}, + {0x012A, /* 0x0023 */ AssistEffect::ASSIST_VANISH}, + {0x012B, /* 0x0024 */ AssistEffect::CHARITY}, + {0x012C, /* 0x0025 */ AssistEffect::INHERITANCE}, + {0x012D, /* 0x0026 */ AssistEffect::FIX}, + {0x012E, /* 0x0027 */ AssistEffect::MUSCULAR}, + {0x012F, /* 0x0028 */ AssistEffect::CHANGE_BODY}, + {0x0130, /* 0x0029 */ AssistEffect::GOD_WHIM}, + {0x0131, /* 0x002A */ AssistEffect::GOLD_RUSH}, + {0x0132, /* 0x002B */ AssistEffect::ASSIST_RETURN}, + {0x0133, /* 0x002C */ AssistEffect::REQUIEM}, + {0x0134, /* 0x002D */ AssistEffect::RANSOM}, + {0x0135, /* 0x002E */ AssistEffect::SIMPLE}, + {0x0136, /* 0x002F */ AssistEffect::SLOW_TIME}, + {0x023F, /* 0x0030 */ AssistEffect::QUICK_TIME}, + {0x0138, /* 0x0031 */ AssistEffect::TERRITORY}, + {0x0139, /* 0x0032 */ AssistEffect::OLD_TYPE}, + {0x013A, /* 0x0033 */ AssistEffect::FLATLAND}, + {0x013B, /* 0x0034 */ AssistEffect::IMMORTALITY}, + {0x013C, /* 0x0035 */ AssistEffect::SNAIL_PACE}, + {0x013D, /* 0x0036 */ AssistEffect::TECH_FIELD}, + {0x013E, /* 0x0037 */ AssistEffect::FOREST_RAIN}, + {0x013F, /* 0x0038 */ AssistEffect::CAVE_WIND}, + {0x0140, /* 0x0039 */ AssistEffect::MINE_BRIGHTNESS}, + {0x0141, /* 0x003A */ AssistEffect::RUIN_DARKNESS}, + {0x0142, /* 0x003B */ AssistEffect::SABER_DANCE}, + {0x0143, /* 0x003C */ AssistEffect::BULLET_STORM}, + {0x0144, /* 0x003D */ AssistEffect::CANE_PALACE}, + {0x0145, /* 0x003E */ AssistEffect::GIANT_GARDEN}, + {0x0146, /* 0x003F */ AssistEffect::MARCH_OF_THE_MEEK}, + {0x0148, /* 0x0040 */ AssistEffect::SUPPORT}, + {0x014A, /* 0x0041 */ AssistEffect::RICH}, + {0x014B, /* 0x0042 */ AssistEffect::REVERSE_CARD}, + {0x014C, /* 0x0043 */ AssistEffect::VENGEANCE}, + {0x014D, /* 0x0044 */ AssistEffect::SQUEEZE}, + {0x014E, /* 0x0045 */ AssistEffect::HOMESICK}, + {0x0240, /* 0x0046 */ AssistEffect::BOMB}, + {0x0241, /* 0x0047 */ AssistEffect::SKIP_TURN}, + {0x0242, /* 0x0048 */ AssistEffect::BATTLE_ROYALE}, + {0x0018, /* 0x0049 */ AssistEffect::DICE_FEVER_PLUS}, + {0x0019, /* 0x004A */ AssistEffect::RICH_PLUS}, + {0x001A, /* 0x004B */ AssistEffect::CHARITY_PLUS}, }); try { return card_id_to_effect.at(card_id); @@ -107,15 +105,13 @@ AssistEffect assist_effect_number_for_card_id(uint16_t card_id) { } } - - AssistServer::AssistServer(shared_ptr server) - : w_server(server), - assist_effects(AssistEffect::NONE), - num_assist_cards_set(0), - client_ids_with_assists(0xFF), - active_assist_effects(AssistEffect::NONE), - num_active_assists(0) { } + : w_server(server), + assist_effects(AssistEffect::NONE), + num_assist_cards_set(0), + client_ids_with_assists(0xFF), + active_assist_effects(AssistEffect::NONE), + num_active_assists(0) {} shared_ptr AssistServer::server() { auto s = this->w_server.lock(); @@ -281,6 +277,4 @@ void AssistServer::recompute_effects() { return; } - - } // namespace Episode3 diff --git a/src/Episode3/AssistServer.hh b/src/Episode3/AssistServer.hh index cbbcf061..cb0606a4 100644 --- a/src/Episode3/AssistServer.hh +++ b/src/Episode3/AssistServer.hh @@ -6,13 +6,11 @@ #include #include "DataIndex.hh" -#include "PlayerState.hh" #include "DeckState.hh" +#include "PlayerState.hh" namespace Episode3 { - - class Server; extern const std::vector ALL_ASSIST_CARD_IDS; @@ -55,6 +53,4 @@ public: std::shared_ptr> set_card_action_metadatas[4]; }; - - } // namespace Episode3 diff --git a/src/Episode3/BattleRecord.cc b/src/Episode3/BattleRecord.cc index 4d8d2c94..c15c0181 100644 --- a/src/Episode3/BattleRecord.cc +++ b/src/Episode3/BattleRecord.cc @@ -9,8 +9,6 @@ using namespace std; namespace Episode3 { - - BattleRecord::Event::Event(StringReader& r) { this->type = r.get(); this->timestamp = r.get_u64l(); @@ -74,19 +72,17 @@ void BattleRecord::Event::serialize(StringWriter& w) const { } } - - BattleRecord::BattleRecord(uint32_t behavior_flags) - : is_writable(true), - behavior_flags(behavior_flags), - battle_start_timestamp(0), - battle_end_timestamp(0) { } + : is_writable(true), + behavior_flags(behavior_flags), + battle_start_timestamp(0), + battle_end_timestamp(0) {} BattleRecord::BattleRecord(const string& data) - : is_writable(false), - behavior_flags(0), - battle_start_timestamp(0), - battle_end_timestamp(0) { + : is_writable(false), + behavior_flags(0), + battle_start_timestamp(0), + battle_end_timestamp(0) { StringReader r(data); uint64_t signature = r.get_u64l(); if (signature != this->SIGNATURE) { @@ -128,7 +124,6 @@ const BattleRecord::Event* BattleRecord::get_first_event() const { return &this->events.front(); } - void BattleRecord::add_player( const PlayerLobbyDataDCGC& lobby_data, const PlayerInventory& inventory, @@ -279,16 +274,14 @@ void BattleRecord::set_battle_end_timestamp() { this->battle_end_timestamp = now(); } - - BattleRecordPlayer::BattleRecordPlayer( shared_ptr rec, shared_ptr base) - : record(rec), - event_it(this->record->events.begin()), - play_start_timestamp(0), - base(base), - next_command_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &BattleRecordPlayer::dispatch_schedule_events, this), event_free) { } + : record(rec), + event_it(this->record->events.begin()), + play_start_timestamp(0), + base(base), + next_command_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &BattleRecordPlayer::dispatch_schedule_events, this), event_free) {} shared_ptr BattleRecordPlayer::get_record() const { return this->record; @@ -377,6 +370,4 @@ void BattleRecordPlayer::schedule_events() { } } - - } // namespace Episode3 diff --git a/src/Episode3/BattleRecord.hh b/src/Episode3/BattleRecord.hh index be7aa39b..9b5bec9f 100644 --- a/src/Episode3/BattleRecord.hh +++ b/src/Episode3/BattleRecord.hh @@ -1,13 +1,13 @@ #pragma once -#include #include +#include #include #include +#include #include #include -#include #include "../Player.hh" @@ -17,8 +17,6 @@ namespace Episode3 { // The comment in Server.hh does not apply to this file (and BattleRecord.cc). - - class BattleRecord { public: struct PlayerEntry { @@ -118,7 +116,4 @@ private: std::shared_ptr next_command_ev; }; - - - } // namespace Episode3 diff --git a/src/Episode3/Card.cc b/src/Episode3/Card.cc index 6e3a0893..5fc35efc 100644 --- a/src/Episode3/Card.cc +++ b/src/Episode3/Card.cc @@ -1,36 +1,34 @@ #include "Card.hh" -#include "Server.hh" #include "../CommandFormats.hh" +#include "Server.hh" using namespace std; namespace Episode3 { - - Card::Card( uint16_t card_id, uint16_t card_ref, uint16_t client_id, shared_ptr server) - : w_server(server), - w_player_state(server->get_player_state(client_id)), - client_id(client_id), - card_id(card_id), - card_ref(card_ref), - card_flags(0), - loc(0, 0, Direction::RIGHT), - facing_direction(Direction::INVALID_FF), - action_chain(), - action_metadata(), - num_ally_fcs_destroyed_at_set_time(0), - num_cards_destroyed_by_team_at_set_time(0), - unknown_a9(1), - last_attack_preliminary_damage(0), - last_attack_final_damage(0), - num_destroyed_ally_fcs(0), - current_defense_power(0) { } + : w_server(server), + w_player_state(server->get_player_state(client_id)), + client_id(client_id), + card_id(card_id), + card_ref(card_ref), + card_flags(0), + loc(0, 0, Direction::RIGHT), + facing_direction(Direction::INVALID_FF), + action_chain(), + action_metadata(), + num_ally_fcs_destroyed_at_set_time(0), + num_cards_destroyed_by_team_at_set_time(0), + unknown_a9(1), + last_attack_preliminary_damage(0), + last_attack_final_damage(0), + num_destroyed_ally_fcs(0), + current_defense_power(0) {} void Card::init() { this->clear_action_chain_and_metadata_and_most_flags(); @@ -117,7 +115,7 @@ ssize_t Card::apply_abnormal_condition( existing_cond_index = z; if (eff.type == ConditionType::MV_BONUS || ((cond.card_definition_effect_index == def_effect_index) && - (cond.card_ref == target_card_ref))) { + (cond.card_ref == target_card_ref))) { break; } } else { @@ -215,8 +213,8 @@ void Card::apply_ap_adjust_assists_to_attack( bool Card::card_type_is_sc_or_creature() const { return (this->def_entry->def.type == CardType::HUNTERS_SC) || - (this->def_entry->def.type == CardType::ARKZ_SC) || - (this->def_entry->def.type == CardType::CREATURE); + (this->def_entry->def.type == CardType::ARKZ_SC) || + (this->def_entry->def.type == CardType::CREATURE); } bool Card::check_card_flag(uint32_t flags) const { @@ -254,7 +252,6 @@ void Card::commit_attack( effective_damage = 0; } - auto attacker_ps = attacker_card->player_state(); attacker_ps->stats.damage_given += effective_damage; this->player_state()->stats.damage_taken += effective_damage; @@ -406,13 +403,13 @@ int32_t Card::error_code_for_move_to_location(const Location& loc) const { return -0x60; } if (!this->server()->ruler_server->card_ref_can_move( - this->client_id, this->card_ref, 1)) { + this->client_id, this->card_ref, 1)) { return -0x7B; } // Note: The original code passes non-null pointers here but ignores the // values written to them; we use nulls since the behavior should be the same. if (!this->server()->ruler_server->get_move_path_length_and_cost( - this->client_id, this->card_ref, loc, nullptr, nullptr)) { + this->client_id, this->card_ref, loc, nullptr, nullptr)) { return -0x79; } return 0; @@ -556,7 +553,7 @@ int32_t Card::move_to_location(const Location& loc) { uint32_t path_cost; uint32_t path_length; if (!this->server()->ruler_server->get_move_path_length_and_cost( - this->client_id, this->card_ref, loc, &path_length, &path_cost)) { + this->client_id, this->card_ref, loc, &path_length, &path_cost)) { return -0x79; } @@ -598,7 +595,6 @@ void Card::propagate_shared_hp_if_needed() { } } - void Card::send_6xB4x4E_4C_4D_if_needed(bool always_send) { ssize_t index = -1; if (this->card_ref == this->player_state()->get_sc_card_ref()) { @@ -940,11 +936,11 @@ void Card::unknown_80237F98(bool require_condition_20_or_21) { if (this->action_chain.conditions[z].type != ConditionType::NONE) { if (!require_condition_20_or_21 || this->server()->card_special->condition_has_when_20_or_21( - this->action_chain.conditions[z])) { + this->action_chain.conditions[z])) { ActionState as; auto& cond = this->action_chain.conditions[z]; if (!this->server()->card_special->is_card_targeted_by_condition( - cond, as, this->shared_from_this())) { + cond, as, this->shared_from_this())) { this->server()->card_special->apply_stat_deltas_to_card_from_condition_and_clear_cond( cond, this->shared_from_this()); should_send_updates = true; @@ -1237,6 +1233,4 @@ void Card::unknown_80237734() { this->send_6xB4x4E_4C_4D_if_needed(); } - - } // namespace Episode3 diff --git a/src/Episode3/Card.hh b/src/Episode3/Card.hh index 27ba73fd..cf691a13 100644 --- a/src/Episode3/Card.hh +++ b/src/Episode3/Card.hh @@ -4,14 +4,12 @@ #include -#include "../Text.hh" #include "../CommandFormats.hh" +#include "../Text.hh" #include "DataIndex.hh" namespace Episode3 { - - class ServerBase; class Server; class PlayerState; @@ -126,6 +124,4 @@ public: int16_t current_defense_power; }; - - } // namespace Episode3 diff --git a/src/Episode3/CardSpecial.cc b/src/Episode3/CardSpecial.cc index 7c003762..26dff4ce 100644 --- a/src/Episode3/CardSpecial.cc +++ b/src/Episode3/CardSpecial.cc @@ -6,8 +6,6 @@ using namespace std; namespace Episode3 { - - CardSpecial::DiceRoll::DiceRoll() { this->clear(); } @@ -20,8 +18,6 @@ void CardSpecial::DiceRoll::clear() { this->unknown_a5 = 0xFFFF; } - - CardSpecial::AttackEnvStats::AttackEnvStats() { this->clear(); } @@ -73,10 +69,9 @@ uint32_t CardSpecial::AttackEnvStats::at(size_t offset) const { return reinterpret_cast*>(this)->at(offset); } - - CardSpecial::CardSpecial(shared_ptr server) - : w_server(server), unknown_a2(0) { } + : w_server(server), + unknown_a2(0) {} shared_ptr CardSpecial::server() { auto s = this->w_server.lock(); @@ -109,11 +104,11 @@ void CardSpecial::adjust_attack_damage_due_to_conditions( } if (!this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - cond.card_ref, - target_card->get_card_ref(), - attacker_card_ref, - cond.card_definition_effect_index, - attack_medium)) { + cond.card_ref, + target_card->get_card_ref(), + attacker_card_ref, + cond.card_definition_effect_index, + attack_medium)) { continue; } @@ -411,7 +406,7 @@ bool CardSpecial::apply_stat_deltas_to_card_from_condition_and_clear_cond( if (hp != ap) { this->send_6xB4x06_for_stat_delta(card, cond_card_ref, 0xA0, hp - ap, 0, 0); this->send_6xB4x06_for_stat_delta(card, cond_card_ref, 0x20, ap - hp, 0, 0); - card->set_current_hp(ap,1,1); + card->set_current_hp(ap, 1, 1); card->ap = hp; this->destroy_card_if_hp_zero(card, cond_card_ref); } @@ -501,7 +496,7 @@ bool CardSpecial::card_has_condition_with_ref( uint16_t match_card_ref) const { size_t z = 0; while ((z < 9) && - ((card->action_chain.conditions[z].type != cond_type) || + ((card->action_chain.conditions[z].type != cond_type) || (card->action_chain.conditions[z].card_ref == card_ref))) { z++; } @@ -532,7 +527,7 @@ void CardSpecial::compute_attack_ap( : AttackMedium::UNKNOWN; uint16_t target_card_ref = target_card->get_card_ref(); - auto check_card = [&](shared_ptr card) -> void{ + auto check_card = [&](shared_ptr card) -> void { if (!card || (card->card_flags & 3)) { return; } @@ -541,19 +536,19 @@ void CardSpecial::compute_attack_ap( if (cond.type == ConditionType::NONE || this->card_ref_has_ability_trap(cond) || !this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - card->action_chain.conditions[cond_index].card_ref, - target_card->get_card_ref(), - attacker_card_ref, - card->action_chain.conditions[cond_index].card_definition_effect_index, - attacker_sc_attack_medium)) { + card->action_chain.conditions[cond_index].card_ref, + target_card->get_card_ref(), + attacker_card_ref, + card->action_chain.conditions[cond_index].card_definition_effect_index, + attacker_sc_attack_medium)) { continue; } auto cond_type = card->action_chain.conditions[cond_index].type; if (((cond_type == ConditionType::UNKNOWN_5F) && - (target_card_ref == card->action_chain.conditions[cond_index].condition_giver_card_ref)) || + (target_card_ref == card->action_chain.conditions[cond_index].condition_giver_card_ref)) || ((cond_type == ConditionType::UNKNOWN_60) && - (target_card_ref == card->action_chain.conditions[cond_index].card_ref))) { + (target_card_ref == card->action_chain.conditions[cond_index].card_ref))) { *out_value = card->action_chain.conditions[cond_index].value8; } } @@ -570,7 +565,7 @@ void CardSpecial::compute_attack_ap( } if (attacker_card && - attacker_card->get_attack_condition_value(ConditionType::UNKNOWN_7D, 0xFFFF,0xFF,0xFFFF, nullptr)) { + attacker_card->get_attack_condition_value(ConditionType::UNKNOWN_7D, 0xFFFF, 0xFF, 0xFFFF, nullptr)) { *out_value = *out_value * 1.5f; } if (target_card && @@ -611,7 +606,8 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats( ast.total_num_set_cards = ps_num_set_cards; uint8_t target_card_team_id = target_card - ? target_card->player_state()->get_team_id() : 0xFF; + ? target_card->player_state()->get_team_id() + : 0xFF; size_t target_team_num_set_cards = 0; size_t condition_giver_team_num_set_cards = 0; @@ -629,19 +625,26 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats( ast.condition_giver_team_num_set_cards = condition_giver_team_num_set_cards; ast.num_native_creatures = this->get_all_set_cards_by_team_and_class( - CardClass::NATIVE_CREATURE, 0xFF, true).size(); + CardClass::NATIVE_CREATURE, 0xFF, true) + .size(); ast.num_a_beast_creatures = this->get_all_set_cards_by_team_and_class( - CardClass::A_BEAST_CREATURE, 0xFF, true).size(); + CardClass::A_BEAST_CREATURE, 0xFF, true) + .size(); ast.num_machine_creatures = this->get_all_set_cards_by_team_and_class( - CardClass::MACHINE_CREATURE, 0xFF, true).size(); + CardClass::MACHINE_CREATURE, 0xFF, true) + .size(); ast.num_dark_creatures = this->get_all_set_cards_by_team_and_class( - CardClass::DARK_CREATURE, 0xFF, true).size(); + CardClass::DARK_CREATURE, 0xFF, true) + .size(); ast.num_sword_type_items = this->get_all_set_cards_by_team_and_class( - CardClass::SWORD_ITEM, 0xFF, true).size(); + CardClass::SWORD_ITEM, 0xFF, true) + .size(); ast.num_gun_type_items = this->get_all_set_cards_by_team_and_class( - CardClass::GUN_ITEM, 0xFF, true).size(); + CardClass::GUN_ITEM, 0xFF, true) + .size(); ast.num_cane_type_items = this->get_all_set_cards_by_team_and_class( - CardClass::CANE_ITEM, 0xFF, true).size(); + CardClass::CANE_ITEM, 0xFF, true) + .size(); ast.num_sword_type_items_on_team = card ? this->get_all_set_cards_by_team_and_class(CardClass::SWORD_ITEM, card->get_team_id(), true).size() : 0; @@ -672,11 +675,14 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats( ast.team_dice_boost = card ? this->server()->team_dice_boost[card->get_team_id()] : 0; ast.effective_ap_if_not_tech = (!attacker_card || (attacker_card->action_chain.chain.attack_medium == AttackMedium::TECH)) - ? 0 : attacker_card->action_chain.chain.damage; + ? 0 + : attacker_card->action_chain.chain.damage; ast.effective_ap_if_not_tech2 = (!attacker_card || (attacker_card->action_chain.chain.attack_medium == AttackMedium::TECH)) - ? 0 : attacker_card->action_chain.chain.damage; + ? 0 + : attacker_card->action_chain.chain.damage; ast.effective_ap_if_not_physical = (!attacker_card || (attacker_card->action_chain.chain.attack_medium == AttackMedium::PHYSICAL)) - ? 0 : attacker_card->action_chain.chain.damage; + ? 0 + : attacker_card->action_chain.chain.damage; ast.sc_effective_ap = attacker_card ? attacker_card->action_chain.chain.damage : 0; ast.attack_bonus = card->action_metadata.attack_bonus; ast.last_attack_preliminary_damage = card->last_attack_preliminary_damage; @@ -707,7 +713,8 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats( // original code. for (z = 0; ((target_card_ref != pa.attacker_card_ref) && (z < 9) && (pa.action_card_refs[z] != 0xFFFF)); - z++) { } + z++) { + } ast.action_cards_ap = 0; ast.action_cards_tp = 0; for (; (z < 9) && (pa.action_card_refs[z] != 0xFFFF); z++) { @@ -789,11 +796,11 @@ shared_ptr CardSpecial::compute_replaced_target_based_on_conditions( continue; } if (!this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - target_card->action_chain.conditions[x].card_ref, - target_card->get_card_ref(), - attacker_card_ref, - target_card->action_chain.conditions[x].card_definition_effect_index, - attack_medium)) { + target_card->action_chain.conditions[x].card_ref, + target_card->get_card_ref(), + attacker_card_ref, + target_card->action_chain.conditions[x].card_definition_effect_index, + attack_medium)) { continue; } if (target_card->action_chain.conditions[x].type != ConditionType::PARRY) { @@ -871,11 +878,11 @@ shared_ptr CardSpecial::compute_replaced_target_based_on_conditions( continue; } if (!this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - other_set_card->action_chain.conditions[z].card_ref, - other_set_card->get_card_ref(), - attacker_card_ref, - other_set_card->action_chain.conditions[z].card_definition_effect_index, - attack_medium)) { + other_set_card->action_chain.conditions[z].card_ref, + other_set_card->get_card_ref(), + attacker_card_ref, + other_set_card->action_chain.conditions[z].card_definition_effect_index, + attack_medium)) { continue; } @@ -896,9 +903,9 @@ shared_ptr CardSpecial::compute_replaced_target_based_on_conditions( (unknown_p4 != 0) && (target_card_ref == other_set_card->action_chain.conditions[z].condition_giver_card_ref)) { candidate_cards.emplace_back(other_set_card); - if (unknown_p11 &&(def_effect_index != 0xFF) && (set_card_ref != 0xFFFF) && + if (unknown_p11 && (def_effect_index != 0xFF) && (set_card_ref != 0xFFFF) && !this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - set_card_ref, sc_card_ref, other_set_card->get_card_ref(), def_effect_index, attack_medium)) { + set_card_ref, sc_card_ref, other_set_card->get_card_ref(), def_effect_index, attack_medium)) { *unknown_p11 = 1; } } @@ -950,11 +957,11 @@ shared_ptr CardSpecial::compute_replaced_target_based_on_conditions( continue; } if (!this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - cond.card_ref, - other_sc->get_card_ref(), - attacker_card_ref, - cond.card_definition_effect_index, - attack_medium)) { + cond.card_ref, + other_sc->get_card_ref(), + attacker_card_ref, + cond.card_definition_effect_index, + attack_medium)) { continue; } @@ -977,7 +984,7 @@ shared_ptr CardSpecial::compute_replaced_target_based_on_conditions( candidate_cards.emplace_back(other_sc); if (unknown_p11 && (def_effect_index != 0xFF) && (set_card_ref != 0xFFFF) && !this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - set_card_ref, sc_card_ref, other_sc->get_card_ref(), def_effect_index, attack_medium)) { + set_card_ref, sc_card_ref, other_sc->get_card_ref(), def_effect_index, attack_medium)) { *unknown_p11 = 1; } } @@ -1262,7 +1269,7 @@ bool CardSpecial::evaluate_effect_arg2_condition( auto set_card = this->server()->card_for_set_card_ref(set_card_ref); bool set_card_has_ability_trap = (set_card && - (this->card_has_condition_with_ref(set_card, ConditionType::ABILITY_TRAP, 0xFFFF, 0xFFFF))); + (this->card_has_condition_with_ref(set_card, ConditionType::ABILITY_TRAP, 0xFFFF, 0xFFFF))); switch (arg2_text[0]) { case 'C': @@ -1392,15 +1399,15 @@ bool CardSpecial::evaluate_effect_arg2_condition( case 13: { auto ce = card->get_definition(); return ((ce->def.card_class() == CardClass::GUARD_ITEM) || - (ce->def.card_class() == CardClass::MAG_ITEM) || - this->server()->ruler_server->find_condition_on_card_ref( - card->get_card_ref(), ConditionType::GUARD_CREATURE, 0, 0, 0)); + (ce->def.card_class() == CardClass::MAG_ITEM) || + this->server()->ruler_server->find_condition_on_card_ref( + card->get_card_ref(), ConditionType::GUARD_CREATURE, 0, 0, 0)); } case 14: return card->get_definition()->def.is_sc(); case 15: return ((card->action_chain.chain.attack_action_card_ref_count == 0) && - (card->action_metadata.defense_card_ref_count == 0)); + (card->action_metadata.defense_card_ref_count == 0)); case 16: return this->server()->ruler_server->card_ref_is_aerial(card->get_card_ref()); case 17: { @@ -1462,14 +1469,14 @@ bool CardSpecial::evaluate_effect_arg2_condition( } } return (this->find_condition_with_parameters( - card, ConditionType::ANY, set_card_ref, ((v % 10) == 0) ? 0xFF : (v % 10)) != nullptr); + card, ConditionType::ANY, set_card_ref, ((v % 10) == 0) ? 0xFF : (v % 10)) != nullptr); } case 'r': return !set_card_has_ability_trap && (random_percent < atoi(arg2_text + 1)); case 's': { auto ce = card->get_definition(); return ((ce->def.self_cost >= arg2_text[1] - '0') && - (ce->def.self_cost <= arg2_text[2] - '0')); + (ce->def.self_cost <= arg2_text[2] - '0')); } case 't': { auto set_card = this->server()->card_for_set_card_ref(set_card_ref); @@ -1597,8 +1604,8 @@ bool CardSpecial::execute_effect( if ((card->card_flags & 3) || (card->action_metadata.check_flag(0x10) && - (cond.card_ref != card->get_card_ref()) && - (cond.condition_giver_card_ref != card->get_card_ref()))) { + (cond.card_ref != card->get_card_ref()) && + (cond.condition_giver_card_ref != card->get_card_ref()))) { unknown_p7 = unknown_p7 & 0xFFFFFFFB; } if (unknown_p7 == 0) { @@ -1887,8 +1894,7 @@ bool CardSpecial::execute_effect( case ConditionType::BONUS_FROM_LEADER: if (unknown_p7 & 1) { - clamped_unknown_p5 = this->count_cards_with_card_id_set_by_player_except_card_ref(expr_value, 0xFFFF) - + (card->action_chain).chain.ap_effect_bonus; + clamped_unknown_p5 = this->count_cards_with_card_id_set_by_player_except_card_ref(expr_value, 0xFFFF) + (card->action_chain).chain.ap_effect_bonus; (card->action_chain).chain.ap_effect_bonus = clamp(clamped_unknown_p5, -99, 99); } return true; @@ -2069,9 +2075,9 @@ bool CardSpecial::execute_effect( auto sc_card = this->server()->card_for_set_card_ref(card_ref); if (sc_card && (sc_card->get_current_hp() > 0)) { if (this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - cond.card_ref, cond.condition_giver_card_ref, - sc_card->get_card_ref(), cond.card_definition_effect_index, - attack_medium)) { + cond.card_ref, cond.condition_giver_card_ref, + sc_card->get_card_ref(), cond.card_definition_effect_index, + attack_medium)) { this->send_6xB4x06_for_stat_delta(sc_card, attacker_card_ref, 0x20, -sc_card->get_current_hp(), 0, 1); sc_card->set_current_hp(0); this->destroy_card_if_hp_zero(sc_card, attacker_card_ref); @@ -2288,11 +2294,11 @@ bool CardSpecial::execute_effect( auto set_card = this->server()->card_for_set_card_ref(card_ref); if (set_card && (set_card->get_current_hp() > 0)) { if (this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - cond.card_ref, - cond.condition_giver_card_ref, - set_card->get_card_ref(), - cond.card_definition_effect_index, - attack_medium)) { + cond.card_ref, + cond.condition_giver_card_ref, + set_card->get_card_ref(), + cond.card_definition_effect_index, + attack_medium)) { this->send_6xB4x06_for_stat_delta( set_card, attacker_card_ref, 0x20, -set_card->get_current_hp(), 0, 1); set_card->set_current_hp(0); @@ -2391,7 +2397,7 @@ void CardSpecial::get_effective_ap_tp( } const char* CardSpecial::get_next_expr_token( - const char *expr, ExpressionTokenType* out_type, int32_t* out_value) const { + const char* expr, ExpressionTokenType* out_type, int32_t* out_value) const { switch (*expr) { case '\0': *out_type = ExpressionTokenType::SPACE; @@ -2427,11 +2433,11 @@ const char* CardSpecial::get_next_expr_token( *out_type = ExpressionTokenType::SPACE; *out_value = 0x27; - static const vector tokens({ + static const vector tokens = { "f", "d", "ap", "tp", "hp", "mhp", "dm", "tdm", "tf", "ac", "php", "dc", "cs", "a", "kap", "ktp", "dn", "hf", "df", "ff", "ef", "bi", "ab", "mc", "dk", "sa", "gn", "wd", "tt", "lv", "adm", "ddm", "sat", - "edm", "ldm", "rdm", "fdm", "ndm", "ehp"}); + "edm", "ldm", "rdm", "fdm", "ndm", "ehp"}; for (size_t z = 0; z < tokens.size(); z++) { if (token_buf == tokens[z]) { *out_type = ExpressionTokenType::REFERENCE; @@ -2467,7 +2473,8 @@ vector> CardSpecial::get_targeted_cards_for_condition( } auto card2 = this->server()->card_for_set_card_ref((as.attacker_card_ref == 0xFFFF) - ? as.original_attacker_card_ref : as.attacker_card_ref); + ? as.original_attacker_card_ref + : as.attacker_card_ref); Location card1_loc; if (!card1) { @@ -2526,7 +2533,8 @@ vector> CardSpecial::get_targeted_cards_for_condition( break; case 4: size_t z; - for (z = 0; (z < 9) && (as.action_card_refs[z] != 0xFFFF) && (as.action_card_refs[z] != card_ref); z++) { } + for (z = 0; (z < 9) && (as.action_card_refs[z] != 0xFFFF) && (as.action_card_refs[z] != card_ref); z++) { + } for (; (z < 9) && (as.action_card_refs[z] != 0xFFFF); z++) { auto result_card = this->server()->card_for_set_card_ref(as.action_card_refs[z]); if (result_card) { @@ -2971,7 +2979,7 @@ vector> CardSpecial::get_targeted_cards_for_condition( for (size_t set_index = 0; set_index < 8; set_index++) { auto result_card = ps->get_set_card(set_index); if (result_card && (card1 != result_card) && - (result_card->get_definition()->def.type == CardType::ITEM)) { + (result_card->get_definition()->def.type == CardType::ITEM)) { bool should_add = true; for (auto c : ret) { if (c == result_card) { @@ -2992,7 +3000,7 @@ vector> CardSpecial::get_targeted_cards_for_condition( vector> filtered_ret; for (auto c : ret) { if (this->server()->ruler_server->check_usability_or_apply_condition_for_card_refs( - card_ref, setter_card_ref, c->get_card_ref(), def_effect_index, attack_medium)) { + card_ref, setter_card_ref, c->get_card_ref(), def_effect_index, attack_medium)) { filtered_ret.emplace_back(c); } } @@ -3176,8 +3184,8 @@ bool CardSpecial::should_cancel_condition_due_to_anti_abnormality( } if ((card->card_flags & 3) || (card->action_metadata.check_flag(0x10) && - (card->get_card_ref() != target_card_ref) && - (card->get_card_ref() != sc_card_ref))) { + (card->get_card_ref() != target_card_ref) && + (card->get_card_ref() != sc_card_ref))) { return true; } auto ce = card->get_definition(); @@ -3519,15 +3527,15 @@ void CardSpecial::unknown_8024C2B0( bool all_targets_matched = false; if (!targeted_cards.empty() && ((card_effect.type == ConditionType::UNKNOWN_64) || - (card_effect.type == ConditionType::MISC_DEFENSE_BONUSES) || - (card_effect.type == ConditionType::MOSTLY_HALFGUARDS))) { + (card_effect.type == ConditionType::MISC_DEFENSE_BONUSES) || + (card_effect.type == ConditionType::MOSTLY_HALFGUARDS))) { size_t count = 0; for (size_t z = 0; z < targeted_cards.size(); z++) { dice_roll.value_used_in_expr = false; string arg2_text = card_effect.arg2; if (this->evaluate_effect_arg2_condition( - as, targeted_cards[z], arg2_text.c_str(), dice_roll, - set_card_ref, sc_card_ref, random_percent, when)) { + as, targeted_cards[z], arg2_text.c_str(), dice_roll, + set_card_ref, sc_card_ref, random_percent, when)) { count++; } if (dice_roll.value_used_in_expr) { @@ -3554,7 +3562,7 @@ void CardSpecial::unknown_8024C2B0( string arg2_str = card_effect.arg2; if (all_targets_matched || this->evaluate_effect_arg2_condition( - as, targeted_cards[z], arg2_str.c_str(), dice_roll, set_card_ref, sc_card_ref, random_percent, when)) { + as, targeted_cards[z], arg2_str.c_str(), dice_roll, set_card_ref, sc_card_ref, random_percent, when)) { auto env_stats = this->compute_attack_env_stats( as, targeted_cards[z], dice_roll, set_card_ref, sc_card_ref); string expr_str = card_effect.expr; @@ -3577,8 +3585,7 @@ void CardSpecial::unknown_8024C2B0( } ssize_t applied_cond_index = -1; - if ((unknown_v1 == 0) && !this->should_cancel_condition_due_to_anti_abnormality( - card_effect, target_card, dice_cmd.effect.target_card_ref, sc_card_ref)) { + if ((unknown_v1 == 0) && !this->should_cancel_condition_due_to_anti_abnormality(card_effect, target_card, dice_cmd.effect.target_card_ref, sc_card_ref)) { applied_cond_index = target_card->apply_abnormal_condition( card_effect, def_effect_index, dice_cmd.effect.target_card_ref, sc_card_ref, value, dice_roll.value, random_percent); // This debug_print call is in the original code. @@ -3713,152 +3720,152 @@ const InterferenceProbabilityEntry* get_interference_probability_entry( uint16_t column_card_id, bool is_attack) { static const InterferenceProbabilityEntry entries[] = { - {0x0004, 0xFF, 0xFF}, - {0x0002, 0x04, 0x00}, - {0x0002, 0x00, 0x0F}, - {0x0003, 0x03, 0x00}, - {0x0003, 0x00, 0x0A}, - {0x0006, 0x01, 0x00}, - {0x0006, 0x00, 0x05}, - {0x0111, 0x01, 0x00}, - {0x0111, 0x00, 0x05}, - {0x0001, 0x03, 0x00}, - {0x0001, 0x00, 0x0A}, - {0x0002, 0xFF, 0xFF}, - {0x0004, 0x04, 0x00}, - {0x0004, 0x00, 0x0F}, - {0x0003, 0x06, 0x00}, - {0x0003, 0x00, 0x14}, - {0x0006, 0x04, 0x00}, - {0x0006, 0x00, 0x0F}, - {0x0003, 0xFF, 0xFF}, - {0x0004, 0x04, 0x00}, - {0x0004, 0x00, 0x0F}, - {0x0002, 0x04, 0x00}, - {0x0002, 0x00, 0x0F}, - {0x0006, 0xFF, 0xFF}, - {0x0002, 0x06, 0x00}, - {0x0002, 0x00, 0x14}, - {0x0111, 0xFF, 0xFF}, - {0x0004, 0x01, 0x00}, - {0x0004, 0x00, 0x05}, - {0x0001, 0x06, 0x00}, - {0x0001, 0x00, 0x14}, - {0x0001, 0xFF, 0xFF}, - {0x0111, 0x04, 0x00}, - {0x0111, 0x00, 0x0F}, - {0x0112, 0xFF, 0xFF}, - {0x0113, 0x06, 0x00}, - {0x0113, 0x00, 0x14}, - {0x0110, 0x06, 0x00}, - {0x0110, 0x00, 0x14}, - {0x0114, 0x01, 0x00}, - {0x0114, 0x00, 0x05}, - {0x011D, 0x02, 0x00}, - {0x011D, 0x00, 0x07}, - {0x0113, 0xFF, 0xFF}, - {0x0003, 0x03, 0x00}, - {0x0003, 0x00, 0x0A}, - {0x0112, 0x03, 0x00}, - {0x0112, 0x00, 0x0A}, - {0x0110, 0xFF, 0xFF}, - {0x0005, 0x03, 0x00}, - {0x0005, 0x00, 0x0A}, - {0x0112, 0x04, 0x00}, - {0x0112, 0x00, 0x0F}, - {0x0005, 0xFF, 0xFF}, - {0x0110, 0x03, 0x00}, - {0x0110, 0x00, 0x0A}, - {0x0114, 0xFF, 0xFF}, - {0x0005, 0x03, 0x00}, - {0x0005, 0x00, 0x0A}, - {0x0110, 0x01, 0x00}, - {0x0110, 0x00, 0x05}, - {0x0115, 0x06, 0x00}, - {0x0115, 0x00, 0x14}, - {0x0115, 0xFF, 0xFF}, - {0x0004, 0x01, 0x00}, - {0x0004, 0x00, 0x05}, - {0x0003, 0x01, 0x00}, - {0x0003, 0x00, 0x05}, - {0x0006, 0x01, 0x00}, - {0x0006, 0x00, 0x05}, - {0x0112, 0x01, 0x00}, - {0x0112, 0x00, 0x05}, - {0x0110, 0x01, 0x00}, - {0x0110, 0x00, 0x05}, - {0x0114, 0x04, 0x00}, - {0x0114, 0x00, 0x0F}, - {0x0008, 0xFF, 0xFF}, - {0x0007, 0x06, 0x00}, - {0x0007, 0x00, 0x14}, - {0x0116, 0x01, 0x00}, - {0x0116, 0x00, 0x05}, - {0x011E, 0x03, 0x00}, - {0x011E, 0x00, 0x0A}, - {0x0118, 0x06, 0x00}, - {0x0118, 0x00, 0x14}, - {0x0007, 0xFF, 0xFF}, - {0x0008, 0x06, 0x00}, - {0x0008, 0x00, 0x14}, - {0x0118, 0x01, 0x00}, - {0x0118, 0x00, 0x05}, - {0x011B, 0x03, 0x00}, - {0x011B, 0x00, 0x0A}, - {0x0116, 0xFF, 0xFF}, - {0x0008, 0x01, 0x00}, - {0x0008, 0x00, 0x05}, - {0x011C, 0x03, 0x00}, - {0x011C, 0x00, 0x0A}, - {0x011A, 0xFF, 0xFF}, - {0x0119, 0x04, 0x00}, - {0x0119, 0x00, 0x0F}, - {0x011D, 0x04, 0x00}, - {0x011D, 0x00, 0x0F}, - {0x0119, 0xFF, 0xFF}, - {0x011A, 0x04, 0x00}, - {0x011A, 0x00, 0x0F}, - {0x011D, 0x04, 0x00}, - {0x011D, 0x00, 0x0F}, - {0x011D, 0xFF, 0xFF}, - {0x0119, 0x04, 0x00}, - {0x0119, 0x00, 0x0F}, - {0x011A, 0x04, 0x00}, - {0x011A, 0x00, 0x0F}, - {0x0112, 0x01, 0x00}, - {0x0112, 0x00, 0x07}, - {0x011E, 0xFF, 0xFF}, - {0x0008, 0x03, 0x00}, - {0x0008, 0x00, 0x0A}, - {0x0118, 0x06, 0x00}, - {0x0118, 0x00, 0x14}, - {0x011C, 0xFF, 0xFF}, - {0x0116, 0x04, 0x00}, - {0x0116, 0x00, 0x0F}, - {0x011E, 0x01, 0x00}, - {0x011E, 0x00, 0x05}, - {0x0118, 0xFF, 0xFF}, - {0x011E, 0x06, 0x00}, - {0x011E, 0x00, 0x14}, - {0x011B, 0xFF, 0xFF}, - {0x0007, 0x03, 0x00}, - {0x0007, 0x00, 0x0A}, - {0x0117, 0x03, 0x00}, - {0x0117, 0x00, 0x0A}, - {0x011F, 0x06, 0x00}, - {0x011F, 0x00, 0x14}, - {0x0117, 0xFF, 0xFF}, - {0x011F, 0x03, 0x00}, - {0x011F, 0x00, 0x0A}, - {0x011B, 0x04, 0x00}, - {0x011B, 0x00, 0x0F}, - {0x011F, 0xFF, 0xFF}, - {0x0007, 0x01, 0x00}, - {0x0007, 0x00, 0x05}, - {0x011B, 0x06, 0x00}, - {0x011B, 0x00, 0x14}, - {0x0117, 0x04, 0x00}, - {0x0117, 0x00, 0x0F}, + {0x0004, 0xFF, 0xFF}, + {0x0002, 0x04, 0x00}, + {0x0002, 0x00, 0x0F}, + {0x0003, 0x03, 0x00}, + {0x0003, 0x00, 0x0A}, + {0x0006, 0x01, 0x00}, + {0x0006, 0x00, 0x05}, + {0x0111, 0x01, 0x00}, + {0x0111, 0x00, 0x05}, + {0x0001, 0x03, 0x00}, + {0x0001, 0x00, 0x0A}, + {0x0002, 0xFF, 0xFF}, + {0x0004, 0x04, 0x00}, + {0x0004, 0x00, 0x0F}, + {0x0003, 0x06, 0x00}, + {0x0003, 0x00, 0x14}, + {0x0006, 0x04, 0x00}, + {0x0006, 0x00, 0x0F}, + {0x0003, 0xFF, 0xFF}, + {0x0004, 0x04, 0x00}, + {0x0004, 0x00, 0x0F}, + {0x0002, 0x04, 0x00}, + {0x0002, 0x00, 0x0F}, + {0x0006, 0xFF, 0xFF}, + {0x0002, 0x06, 0x00}, + {0x0002, 0x00, 0x14}, + {0x0111, 0xFF, 0xFF}, + {0x0004, 0x01, 0x00}, + {0x0004, 0x00, 0x05}, + {0x0001, 0x06, 0x00}, + {0x0001, 0x00, 0x14}, + {0x0001, 0xFF, 0xFF}, + {0x0111, 0x04, 0x00}, + {0x0111, 0x00, 0x0F}, + {0x0112, 0xFF, 0xFF}, + {0x0113, 0x06, 0x00}, + {0x0113, 0x00, 0x14}, + {0x0110, 0x06, 0x00}, + {0x0110, 0x00, 0x14}, + {0x0114, 0x01, 0x00}, + {0x0114, 0x00, 0x05}, + {0x011D, 0x02, 0x00}, + {0x011D, 0x00, 0x07}, + {0x0113, 0xFF, 0xFF}, + {0x0003, 0x03, 0x00}, + {0x0003, 0x00, 0x0A}, + {0x0112, 0x03, 0x00}, + {0x0112, 0x00, 0x0A}, + {0x0110, 0xFF, 0xFF}, + {0x0005, 0x03, 0x00}, + {0x0005, 0x00, 0x0A}, + {0x0112, 0x04, 0x00}, + {0x0112, 0x00, 0x0F}, + {0x0005, 0xFF, 0xFF}, + {0x0110, 0x03, 0x00}, + {0x0110, 0x00, 0x0A}, + {0x0114, 0xFF, 0xFF}, + {0x0005, 0x03, 0x00}, + {0x0005, 0x00, 0x0A}, + {0x0110, 0x01, 0x00}, + {0x0110, 0x00, 0x05}, + {0x0115, 0x06, 0x00}, + {0x0115, 0x00, 0x14}, + {0x0115, 0xFF, 0xFF}, + {0x0004, 0x01, 0x00}, + {0x0004, 0x00, 0x05}, + {0x0003, 0x01, 0x00}, + {0x0003, 0x00, 0x05}, + {0x0006, 0x01, 0x00}, + {0x0006, 0x00, 0x05}, + {0x0112, 0x01, 0x00}, + {0x0112, 0x00, 0x05}, + {0x0110, 0x01, 0x00}, + {0x0110, 0x00, 0x05}, + {0x0114, 0x04, 0x00}, + {0x0114, 0x00, 0x0F}, + {0x0008, 0xFF, 0xFF}, + {0x0007, 0x06, 0x00}, + {0x0007, 0x00, 0x14}, + {0x0116, 0x01, 0x00}, + {0x0116, 0x00, 0x05}, + {0x011E, 0x03, 0x00}, + {0x011E, 0x00, 0x0A}, + {0x0118, 0x06, 0x00}, + {0x0118, 0x00, 0x14}, + {0x0007, 0xFF, 0xFF}, + {0x0008, 0x06, 0x00}, + {0x0008, 0x00, 0x14}, + {0x0118, 0x01, 0x00}, + {0x0118, 0x00, 0x05}, + {0x011B, 0x03, 0x00}, + {0x011B, 0x00, 0x0A}, + {0x0116, 0xFF, 0xFF}, + {0x0008, 0x01, 0x00}, + {0x0008, 0x00, 0x05}, + {0x011C, 0x03, 0x00}, + {0x011C, 0x00, 0x0A}, + {0x011A, 0xFF, 0xFF}, + {0x0119, 0x04, 0x00}, + {0x0119, 0x00, 0x0F}, + {0x011D, 0x04, 0x00}, + {0x011D, 0x00, 0x0F}, + {0x0119, 0xFF, 0xFF}, + {0x011A, 0x04, 0x00}, + {0x011A, 0x00, 0x0F}, + {0x011D, 0x04, 0x00}, + {0x011D, 0x00, 0x0F}, + {0x011D, 0xFF, 0xFF}, + {0x0119, 0x04, 0x00}, + {0x0119, 0x00, 0x0F}, + {0x011A, 0x04, 0x00}, + {0x011A, 0x00, 0x0F}, + {0x0112, 0x01, 0x00}, + {0x0112, 0x00, 0x07}, + {0x011E, 0xFF, 0xFF}, + {0x0008, 0x03, 0x00}, + {0x0008, 0x00, 0x0A}, + {0x0118, 0x06, 0x00}, + {0x0118, 0x00, 0x14}, + {0x011C, 0xFF, 0xFF}, + {0x0116, 0x04, 0x00}, + {0x0116, 0x00, 0x0F}, + {0x011E, 0x01, 0x00}, + {0x011E, 0x00, 0x05}, + {0x0118, 0xFF, 0xFF}, + {0x011E, 0x06, 0x00}, + {0x011E, 0x00, 0x14}, + {0x011B, 0xFF, 0xFF}, + {0x0007, 0x03, 0x00}, + {0x0007, 0x00, 0x0A}, + {0x0117, 0x03, 0x00}, + {0x0117, 0x00, 0x0A}, + {0x011F, 0x06, 0x00}, + {0x011F, 0x00, 0x14}, + {0x0117, 0xFF, 0xFF}, + {0x011F, 0x03, 0x00}, + {0x011F, 0x00, 0x0A}, + {0x011B, 0x04, 0x00}, + {0x011B, 0x00, 0x0F}, + {0x011F, 0xFF, 0xFF}, + {0x0007, 0x01, 0x00}, + {0x0007, 0x00, 0x05}, + {0x011B, 0x06, 0x00}, + {0x011B, 0x00, 0x14}, + {0x0117, 0x04, 0x00}, + {0x0117, 0x00, 0x0F}, }; constexpr size_t num_entries = sizeof(entries) / sizeof(entries[0]); @@ -4526,6 +4533,4 @@ vector> CardSpecial::find_all_sc_cards_of_class( return ret; } - - } // namespace Episode3 diff --git a/src/Episode3/CardSpecial.hh b/src/Episode3/CardSpecial.hh index aedf3354..d47c147f 100644 --- a/src/Episode3/CardSpecial.hh +++ b/src/Episode3/CardSpecial.hh @@ -9,8 +9,6 @@ namespace Episode3 { - - struct InterferenceProbabilityEntry { uint16_t card_id; uint8_t attack_probability; @@ -22,8 +20,6 @@ const InterferenceProbabilityEntry* get_interference_probability_entry( uint16_t column_card_id, bool is_attack); - - class CardSpecial { public: enum class ExpressionTokenType { @@ -224,7 +220,7 @@ public: int16_t ap, int16_t tp); const char* get_next_expr_token( - const char *expr, ExpressionTokenType* out_type, int32_t* out_value) const; + const char* expr, ExpressionTokenType* out_type, int32_t* out_value) const; std::vector> get_targeted_cards_for_condition( uint16_t card_ref, uint8_t def_effect_index, @@ -341,6 +337,4 @@ private: uint16_t unknown_a2; }; - - } // namespace Episode3 diff --git a/src/Episode3/DataIndex.cc b/src/Episode3/DataIndex.cc index c51f2654..d65c1f20 100644 --- a/src/Episode3/DataIndex.cc +++ b/src/Episode3/DataIndex.cc @@ -8,18 +8,16 @@ #include #include -#include "../Loggers.hh" #include "../Compression.hh" +#include "../Loggers.hh" #include "../PSOEncryption.hh" -#include "../Text.hh" #include "../Quest.hh" +#include "../Text.hh" using namespace std; namespace Episode3 { - - const char* name_for_attack_medium(AttackMedium medium) { switch (medium) { case AttackMedium::UNKNOWN: @@ -37,12 +35,13 @@ const char* name_for_attack_medium(AttackMedium medium) { } } - - -Location::Location() : Location(0, 0) { } -Location::Location(uint8_t x, uint8_t y) : Location(x, y, Direction::RIGHT) { } +Location::Location() : Location(0, 0) {} +Location::Location(uint8_t x, uint8_t y) : Location(x, y, Direction::RIGHT) {} Location::Location(uint8_t x, uint8_t y, Direction direction) - : x(x), y(y), direction(direction), unused(0) { } + : x(x), + y(y), + direction(direction), + unused(0) {} bool Location::operator==(const Location& other) const { return (this->x == other.x) && @@ -56,7 +55,7 @@ bool Location::operator!=(const Location& other) const { std::string Location::str() const { return string_printf("Location[x=%hhu, y=%hhu, dir=%s, u=%hhu]", - this->x, this->y, name_for_direction(this->direction), this->unused); + this->x, this->y, name_for_direction(this->direction), this->unused); } void Location::clear() { @@ -73,8 +72,6 @@ void Location::clear_FF() { this->unused = 0xFF; } - - Direction turn_left(Direction d) { switch (d) { case Direction::RIGHT: @@ -137,65 +134,61 @@ const char* name_for_direction(Direction d) { } } - - bool card_class_is_tech_like(CardClass cc) { return (cc == CardClass::TECH) || (cc == CardClass::PHOTON_BLAST) || (cc == CardClass::BOSS_TECH); } - - static const vector name_for_card_type({ - "HunterSC", - "ArkzSC", - "Item", - "Creature", - "Action", - "Assist", + "HunterSC", + "ArkzSC", + "Item", + "Creature", + "Action", + "Assist", }); static const unordered_map description_for_expr_token({ - {"f", "Number of FCs controlled by current SC"}, - {"d", "Die roll"}, - {"ap", "Attacker effective AP"}, - {"tp", "Attacker effective TP"}, - {"hp", "Current HP"}, - {"mhp", "Maximum HP"}, - {"dm", "Physical damage"}, - {"tdm", "Technique damage"}, - {"tf", "Number of SC\'s destroyed FCs"}, - {"ac", "Remaining ATK points"}, - {"php", "Maximum HP"}, - {"dc", "Die roll"}, - {"cs", "Card set cost"}, - {"a", "Number of FCs on all teams"}, - {"kap", "Action cards AP"}, - {"ktp", "Action cards TP"}, - {"dn", "Unknown: dn"}, - {"hf", "Number of item or creature cards in hand"}, - {"df", "Number of destroyed ally FCs (including SC\'s own)"}, - {"ff", "Number of ally FCs (including SC\'s own)"}, - {"ef", "Number of enemy FCs"}, - {"bi", "Number of Native FCs on either team"}, - {"ab", "Number of A.Beast FCs on either team"}, - {"mc", "Number of Machine FCs on either team"}, - {"dk", "Number of Dark FCs on either team"}, - {"sa", "Number of Sword-type items on either team"}, - {"gn", "Number of Gun-type items on either team"}, - {"wd", "Number of Cane-type items on either team"}, - {"tt", "Physical damage"}, - {"lv", "Dice boost"}, - {"adm", "SC attack damage"}, - {"ddm", "Defending damage"}, - {"sat", "Number of Sword-type items on SC\'s team"}, - {"edm", "Defending damage"}, // TODO: How is this different from ddm? - {"ldm", "Unknown: ldm"}, // Unused - {"rdm", "Defending damage"}, // TODO: How is this different from ddm/edm? - {"fdm", "Final damage (after defense)"}, - {"ndm", "Unknown: ndm"}, // Unused - {"ehp", "Attacker HP"}, + {"f", "Number of FCs controlled by current SC"}, + {"d", "Die roll"}, + {"ap", "Attacker effective AP"}, + {"tp", "Attacker effective TP"}, + {"hp", "Current HP"}, + {"mhp", "Maximum HP"}, + {"dm", "Physical damage"}, + {"tdm", "Technique damage"}, + {"tf", "Number of SC\'s destroyed FCs"}, + {"ac", "Remaining ATK points"}, + {"php", "Maximum HP"}, + {"dc", "Die roll"}, + {"cs", "Card set cost"}, + {"a", "Number of FCs on all teams"}, + {"kap", "Action cards AP"}, + {"ktp", "Action cards TP"}, + {"dn", "Unknown: dn"}, + {"hf", "Number of item or creature cards in hand"}, + {"df", "Number of destroyed ally FCs (including SC\'s own)"}, + {"ff", "Number of ally FCs (including SC\'s own)"}, + {"ef", "Number of enemy FCs"}, + {"bi", "Number of Native FCs on either team"}, + {"ab", "Number of A.Beast FCs on either team"}, + {"mc", "Number of Machine FCs on either team"}, + {"dk", "Number of Dark FCs on either team"}, + {"sa", "Number of Sword-type items on either team"}, + {"gn", "Number of Gun-type items on either team"}, + {"wd", "Number of Cane-type items on either team"}, + {"tt", "Physical damage"}, + {"lv", "Dice boost"}, + {"adm", "SC attack damage"}, + {"ddm", "Defending damage"}, + {"sat", "Number of Sword-type items on SC\'s team"}, + {"edm", "Defending damage"}, // TODO: How is this different from ddm? + {"ldm", "Unknown: ldm"}, // Unused + {"rdm", "Defending damage"}, // TODO: How is this different from ddm/edm? + {"fdm", "Final damage (after defense)"}, + {"ndm", "Unknown: ndm"}, // Unused + {"ehp", "Attacker HP"}, }); // Arguments are encoded as 3-character null-terminated strings (why?!), and are @@ -224,82 +217,82 @@ static const unordered_map description_for_expr_token({ // tXX = lasts XX turns, or activate after XX turns static const vector description_for_n_condition({ - /* n00 */ "Always true", - /* n01 */ "Card is Hunters-side SC", - /* n02 */ "Destroyed with a single attack", - /* n03 */ "Technique or PB action card was used", - /* n04 */ "Attack has Pierce", - /* n05 */ "Attack has Rampage", - /* n06 */ "Native attribute", - /* n07 */ "A.Beast attribute", - /* n08 */ "Machine attribute", - /* n09 */ "Dark attribute", - /* n10 */ "Sword-type item", - /* n11 */ "Gun-type item", - /* n12 */ "Cane-type item", - /* n13 */ "Guard item or MAG", - /* n14 */ "Story Character", - /* n15 */ "Attacker does not use action cards", - /* n16 */ "Aerial attribute", - /* n17 */ "Same AP as opponent", - /* n18 */ "Any target is an SC", - /* n19 */ "Has Paralyzed condition", - /* n20 */ "Has Frozen condition", - /* n21 */ "???", // TODO: This appears related to Pierce/Rampage - /* n22 */ "???", // TODO: This appears related to Pierce/Rampage + /* n00 */ "Always true", + /* n01 */ "Card is Hunters-side SC", + /* n02 */ "Destroyed with a single attack", + /* n03 */ "Technique or PB action card was used", + /* n04 */ "Attack has Pierce", + /* n05 */ "Attack has Rampage", + /* n06 */ "Native attribute", + /* n07 */ "A.Beast attribute", + /* n08 */ "Machine attribute", + /* n09 */ "Dark attribute", + /* n10 */ "Sword-type item", + /* n11 */ "Gun-type item", + /* n12 */ "Cane-type item", + /* n13 */ "Guard item or MAG", + /* n14 */ "Story Character", + /* n15 */ "Attacker does not use action cards", + /* n16 */ "Aerial attribute", + /* n17 */ "Same AP as opponent", + /* n18 */ "Any target is an SC", + /* n19 */ "Has Paralyzed condition", + /* n20 */ "Has Frozen condition", + /* n21 */ "???", // TODO: This appears related to Pierce/Rampage + /* n22 */ "???", // TODO: This appears related to Pierce/Rampage }); static const vector description_for_p_target({ - /* p00 */ "Unknown: p00", // Unused; probably invalid - /* p01 */ "SC / FC who set the card", - /* p02 */ "Attacking SC / FC", - /* p03 */ "Unknown: p03", // Unused - /* p04 */ "Unknown: p04", // Unused - /* p05 */ "SC / FC who set the card", // Identical to p01 - /* p06 */ "??? (TODO)", - /* p07 */ "??? (TODO; Weakness)", - /* p08 */ "FC\'s owner SC", - /* p09 */ "Unknown: p09", // Unused - /* p10 */ "All ally FCs", - /* p11 */ "All ally FCs", // TODO: how is this different from p10? - /* p12 */ "All non-aerial FCs on both teams", - /* p13 */ "All FCs on both teams that are Frozen", - /* p14 */ "All FCs on both teams that have <= 3 HP", - /* p15 */ "All FCs except SCs", // TODO: used during attacks only? - /* p16 */ "All FCs except SCs", // TODO: used during attacks only? how is this different from p15? - /* p17 */ "This card", - /* p18 */ "SC who equipped this card", - /* p19 */ "Unknown: p19", // Unused - /* p20 */ "Unknown: p20", // Unused - /* p21 */ "Unknown: p21", // Unused - /* p22 */ "All characters (SCs & FCs) including this card", // TODO: But why does Shifta apply only to allies then? - /* p23 */ "All characters (SCs & FCs) except this card", - /* p24 */ "All FCs on both teams that have Paralysis", - /* p25 */ "Unknown: p25", // Unused - /* p26 */ "Unknown: p26", // Unused - /* p27 */ "Unknown: p27", // Unused - /* p28 */ "Unknown: p28", // Unused - /* p29 */ "Unknown: p29", // Unused - /* p30 */ "Unknown: p30", // Unused - /* p31 */ "Unknown: p31", // Unused - /* p32 */ "Unknown: p32", // Unused - /* p33 */ "Unknown: p33", // Unused - /* p34 */ "Unknown: p34", // Unused - /* p35 */ "All characters (SCs & FCs) within range", // Used for Explosion effect - /* p36 */ "All ally SCs within range, but not the caster", // Resta - /* p37 */ "All FCs or all opponent FCs (TODO)", // TODO: when to use which selector? is a3 involved here somehow? - /* p38 */ "All allies except items within range (and not this card)", - /* p39 */ "All FCs that cost 4 or more points", - /* p40 */ "All FCs that cost 3 or fewer points", - /* p41 */ "Unknown: p41", // Unused - /* p42 */ "Attacker during defense phase", // Only used by TP Defense - /* p43 */ "Owner SC of defending FC during attack", - /* p44 */ "SC\'s own creature FCs within range", - /* p45 */ "Both attacker and defender", // Used for Snatch, which moves EXP from one to the other - /* p46 */ "All SCs & FCs one space left or right of this card", - /* p47 */ "FC\'s owner Boss SC", // Only used for Gibbles+ which explicitly mentions Boss SC, so it looks like this is p08 but for bosses - /* p48 */ "Everything within range, including this card\'s user", // Madness - /* p49 */ "All ally FCs within range except this card", + /* p00 */ "Unknown: p00", // Unused; probably invalid + /* p01 */ "SC / FC who set the card", + /* p02 */ "Attacking SC / FC", + /* p03 */ "Unknown: p03", // Unused + /* p04 */ "Unknown: p04", // Unused + /* p05 */ "SC / FC who set the card", // Identical to p01 + /* p06 */ "??? (TODO)", + /* p07 */ "??? (TODO; Weakness)", + /* p08 */ "FC\'s owner SC", + /* p09 */ "Unknown: p09", // Unused + /* p10 */ "All ally FCs", + /* p11 */ "All ally FCs", // TODO: how is this different from p10? + /* p12 */ "All non-aerial FCs on both teams", + /* p13 */ "All FCs on both teams that are Frozen", + /* p14 */ "All FCs on both teams that have <= 3 HP", + /* p15 */ "All FCs except SCs", // TODO: used during attacks only? + /* p16 */ "All FCs except SCs", // TODO: used during attacks only? how is this different from p15? + /* p17 */ "This card", + /* p18 */ "SC who equipped this card", + /* p19 */ "Unknown: p19", // Unused + /* p20 */ "Unknown: p20", // Unused + /* p21 */ "Unknown: p21", // Unused + /* p22 */ "All characters (SCs & FCs) including this card", // TODO: But why does Shifta apply only to allies then? + /* p23 */ "All characters (SCs & FCs) except this card", + /* p24 */ "All FCs on both teams that have Paralysis", + /* p25 */ "Unknown: p25", // Unused + /* p26 */ "Unknown: p26", // Unused + /* p27 */ "Unknown: p27", // Unused + /* p28 */ "Unknown: p28", // Unused + /* p29 */ "Unknown: p29", // Unused + /* p30 */ "Unknown: p30", // Unused + /* p31 */ "Unknown: p31", // Unused + /* p32 */ "Unknown: p32", // Unused + /* p33 */ "Unknown: p33", // Unused + /* p34 */ "Unknown: p34", // Unused + /* p35 */ "All characters (SCs & FCs) within range", // Used for Explosion effect + /* p36 */ "All ally SCs within range, but not the caster", // Resta + /* p37 */ "All FCs or all opponent FCs (TODO)", // TODO: when to use which selector? is a3 involved here somehow? + /* p38 */ "All allies except items within range (and not this card)", + /* p39 */ "All FCs that cost 4 or more points", + /* p40 */ "All FCs that cost 3 or fewer points", + /* p41 */ "Unknown: p41", // Unused + /* p42 */ "Attacker during defense phase", // Only used by TP Defense + /* p43 */ "Owner SC of defending FC during attack", + /* p44 */ "SC\'s own creature FCs within range", + /* p45 */ "Both attacker and defender", // Used for Snatch, which moves EXP from one to the other + /* p46 */ "All SCs & FCs one space left or right of this card", + /* p47 */ "FC\'s owner Boss SC", // Only used for Gibbles+ which explicitly mentions Boss SC, so it looks like this is p08 but for bosses + /* p48 */ "Everything within range, including this card\'s user", // Madness + /* p49 */ "All ally FCs within range except this card", }); struct ConditionDescription { @@ -309,132 +302,132 @@ struct ConditionDescription { }; static const vector description_for_condition_type({ - /* 0x00 */ {false, "NONE", nullptr}, - /* 0x01 */ {true, "AP_BOOST", "Temporarily increase AP by N"}, - /* 0x02 */ {false, "RAMPAGE", "Rampage"}, - /* 0x03 */ {true, "MULTI_STRIKE", "Duplicate attack N times"}, - /* 0x04 */ {true, "DAMAGE_MOD_1", "Set attack damage / AP to N after action cards applied (step 1)"}, - /* 0x05 */ {false, "IMMOBILE", "Give Immobile condition"}, - /* 0x06 */ {false, "HOLD", "Give Hold condition"}, - /* 0x07 */ {false, "UNKNOWN_07", nullptr}, - /* 0x08 */ {true, "TP_BOOST", "Add N TP temporarily during attack"}, - /* 0x09 */ {true, "GIVE_DAMAGE", "Cause direct N HP loss"}, - /* 0x0A */ {false, "GUOM", "Give Guom condition"}, - /* 0x0B */ {false, "PARALYZE", "Give Paralysis condition"}, - /* 0x0C */ {false, "UNKNOWN_0C", nullptr}, - /* 0x0D */ {false, "A_H_SWAP", "Swap AP and HP temporarily"}, - /* 0x0E */ {false, "PIERCE", "Attack SC directly even if they have items equipped"}, - /* 0x0F */ {false, "UNKNOWN_0F", nullptr}, - /* 0x10 */ {true, "HEAL", "Increase HP by N"}, - /* 0x11 */ {false, "RETURN_TO_HAND", "Return card to hand"}, - /* 0x12 */ {false, "UNKNOWN_12", nullptr}, - /* 0x13 */ {false, "UNKNOWN_13", nullptr}, - /* 0x14 */ {false, "ACID", "Give Acid condition"}, - /* 0x15 */ {false, "UNKNOWN_15", nullptr}, - /* 0x16 */ {true, "MIGHTY_KNUCKLE", "Temporarily increase AP by N, and set ATK dice to zero"}, - /* 0x17 */ {true, "UNIT_BLOW", "Temporarily increase AP by N * number of this card set within phase"}, - /* 0x18 */ {false, "CURSE", "Give Curse condition"}, - /* 0x19 */ {false, "COMBO_AP", "Temporarily increase AP by number of this card set within phase"}, - /* 0x1A */ {false, "PIERCE_RAMPAGE_BLOCK", "Block attack if Pierce/Rampage (?)"}, - /* 0x1B */ {false, "ABILITY_TRAP", "Temporarily disable opponent abilities"}, - /* 0x1C */ {false, "FREEZE", "Give Freeze condition"}, - /* 0x1D */ {false, "ANTI_ABNORMALITY_1", "Cure all conditions"}, - /* 0x1E */ {false, "UNKNOWN_1E", nullptr}, - /* 0x1F */ {false, "EXPLOSION", "Damage all SCs and FCs by number of this same card set * 2"}, - /* 0x20 */ {false, "UNKNOWN_20", nullptr}, - /* 0x21 */ {false, "UNKNOWN_21", nullptr}, - /* 0x22 */ {false, "UNKNOWN_22", nullptr}, - /* 0x23 */ {false, "RETURN_TO_DECK", "Cancel discard and move to bottom of deck instead"}, - /* 0x24 */ {false, "AERIAL", "Give Aerial status"}, - /* 0x25 */ {true, "AP_LOSS", "Make attacker temporarily lose N AP during defense"}, - /* 0x26 */ {true, "BONUS_FROM_LEADER", "Gain AP equal to the number of cards of type N on the field"}, - /* 0x27 */ {false, "FREE_MANEUVER", "Enable movement over occupied tiles"}, - /* 0x28 */ {false, "HASTE", "Make move actions free"}, - /* 0x29 */ {true, "CLONE", "Make setting this card free if at least one card of type N is already on the field"}, - /* 0x2A */ {true, "DEF_DISABLE_BY_COST", "Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive"}, - /* 0x2B */ {true, "FILIAL", "Increase controlling SC\'s HP by N when this card is destroyed"}, - /* 0x2C */ {true, "SNATCH", "Steal N EXP during attack"}, - /* 0x2D */ {true, "HAND_DISRUPTER", "Discard N cards from hand immediately"}, - /* 0x2E */ {false, "DROP", "Give Drop condition"}, - /* 0x2F */ {false, "ACTION_DISRUPTER", "Destroy all action cards used by attacker"}, - /* 0x30 */ {true, "SET_HP", "Set HP to N"}, - /* 0x31 */ {false, "NATIVE_SHIELD", "Block attacks from Native creatures"}, - /* 0x32 */ {false, "A_BEAST_SHIELD", "Block attacks from A.Beast creatures"}, - /* 0x33 */ {false, "MACHINE_SHIELD", "Block attacks from Machine creatures"}, - /* 0x34 */ {false, "DARK_SHIELD", "Block attacks from Dark creatures"}, - /* 0x35 */ {false, "SWORD_SHIELD", "Block attacks from Sword items"}, - /* 0x36 */ {false, "GUN_SHIELD", "Block attacks from Gun items"}, - /* 0x37 */ {false, "CANE_SHIELD", "Block attacks from Cane items"}, - /* 0x38 */ {false, "UNKNOWN_38", nullptr}, - /* 0x39 */ {false, "UNKNOWN_39", nullptr}, - /* 0x3A */ {false, "DEFENDER", "Make attacks go to setter of this card instead of original target"}, - /* 0x3B */ {false, "SURVIVAL_DECOYS", "Redirect damage for multi-sided attack"}, - /* 0x3C */ {true, "GIVE_OR_TAKE_EXP", "Give N EXP, or take if N is negative"}, - /* 0x3D */ {false, "UNKNOWN_3D", nullptr}, - /* 0x3E */ {false, "DEATH_COMPANION", "If this card has 1 or 2 HP, set its HP to N"}, - /* 0x3F */ {true, "EXP_DECOY", "If defender has EXP, lose EXP instead of getting damage when attacked"}, - /* 0x40 */ {true, "SET_MV", "Set MV to N"}, - /* 0x41 */ {true, "GROUP", "Temporarily increase AP by N * number of this card on field, excluding itself"}, - /* 0x42 */ {false, "BERSERK", "User of this card receives the same damage as target, and isn\'t helped by target\'s defense cards"}, - /* 0x43 */ {false, "GUARD_CREATURE", "Attacks on controlling SC damage this card instead"}, - /* 0x44 */ {false, "TECH", "Technique cards cost 1 fewer ATK point"}, - /* 0x45 */ {false, "BIG_SWING", "Increase all attacking ATK costs by 1"}, - /* 0x46 */ {false, "UNKNOWN_46", nullptr}, - /* 0x47 */ {false, "SHIELD_WEAPON", "Limit attacker\'s choice of target to guard items"}, - /* 0x48 */ {false, "ATK_DICE_BOOST", "Increase ATK dice roll by 1"}, - /* 0x49 */ {false, "UNKNOWN_49", nullptr}, - /* 0x4A */ {false, "MAJOR_PIERCE", "If SC has over half of max HP, attacks target SC instead of equipped items"}, - /* 0x4B */ {false, "HEAVY_PIERCE", "If SC has 3 or more items equipped, attacks target SC instead of equipped items"}, - /* 0x4C */ {false, "MAJOR_RAMPAGE", "If SC has over half of max HP, attacks target SC and all equipped items"}, - /* 0x4D */ {false, "HEAVY_RAMPAGE", "If SC has 3 or more items equipped, attacks target SC and all equipped items"}, - /* 0x4E */ {true, "AP_GROWTH", "Permanently increase AP by N"}, - /* 0x4F */ {true, "TP_GROWTH", "Permanently increase TP by N"}, - /* 0x50 */ {true, "REBORN", "If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded"}, - /* 0x51 */ {true, "COPY", "Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent\'s values"}, - /* 0x52 */ {false, "UNKNOWN_52", nullptr}, - /* 0x53 */ {true, "MISC_GUARDS", "Add N to card\'s defense value"}, - /* 0x54 */ {true, "AP_OVERRIDE", "Set AP to N temporarily"}, - /* 0x55 */ {true, "TP_OVERRIDE", "Set TP to N temporarily"}, - /* 0x56 */ {false, "RETURN", "Return card to hand on destruction instead of discarding"}, - /* 0x57 */ {false, "A_T_SWAP_PERM", "Permanently swap AP and TP"}, - /* 0x58 */ {false, "A_H_SWAP_PERM", "Permanently swap AP and HP"}, - /* 0x59 */ {true, "SLAYERS_ASSASSINS", "Temporarily increase AP during attack"}, - /* 0x5A */ {false, "ANTI_ABNORMALITY_2", "Remove all conditions"}, - /* 0x5B */ {false, "FIXED_RANGE", "Use SC\'s range instead of weapon or attack card ranges"}, - /* 0x5C */ {false, "ELUDE", "SC does not lose HP when equipped items are destroyed"}, - /* 0x5D */ {false, "PARRY", "Forward attack to a random FC within one tile of original target, excluding attacker and original target"}, - /* 0x5E */ {false, "BLOCK_ATTACK", "Completely block attack"}, - /* 0x5F */ {false, "UNKNOWN_5F", nullptr}, - /* 0x60 */ {false, "UNKNOWN_60", nullptr}, - /* 0x61 */ {true, "COMBO_TP", "Gain TP equal to the number of cards of type N on the field"}, - /* 0x62 */ {true, "MISC_AP_BONUSES", "Temporarily increase AP by N"}, - /* 0x63 */ {true, "MISC_TP_BONUSES", "Temporarily increase TP by N"}, - /* 0x64 */ {false, "UNKNOWN_64", nullptr}, - /* 0x65 */ {true, "MISC_DEFENSE_BONUSES", "Decrease damage by N"}, - /* 0x66 */ {true, "MOSTLY_HALFGUARDS", "Reduce damage from incoming attack by N"}, - /* 0x67 */ {false, "PERIODIC_FIELD", "Swap immunity to tech or physical attacks"}, - /* 0x68 */ {false, "FC_LIMIT_BY_COUNT", "Change FC limit from 8 ATK points total to 4 FCs total"}, - /* 0x69 */ {false, "UNKNOWN_69", nullptr}, - /* 0x6A */ {true, "MV_BONUS", "Increase MV by N"}, - /* 0x6B */ {true, "FORWARD_DAMAGE", "Give N damage back to attacker during defense (?) (TODO)"}, - /* 0x6C */ {true, "WEAK_SPOT_INFLUENCE", "Temporarily decrease AP by N"}, - /* 0x6D */ {true, "DAMAGE_MODIFIER_2", "Set attack damage / AP after action cards applied (step 2)"}, - /* 0x6E */ {true, "WEAK_HIT_BLOCK", "Block all attacks of N damage or less"}, - /* 0x6F */ {true, "AP_SILENCE", "Temporarily decrease AP of opponent by N"}, - /* 0x70 */ {true, "TP_SILENCE", "Temporarily decrease TP of opponent by N"}, - /* 0x71 */ {false, "A_T_SWAP", "Temporarily swap AP and TP"}, - /* 0x72 */ {true, "HALFGUARD", "Halve damage from attacks that would inflict N or more damage"}, - /* 0x73 */ {false, "UNKNOWN_73", nullptr}, - /* 0x74 */ {true, "RAMPAGE_AP_LOSS", "Temporarily reduce AP by N"}, - /* 0x75 */ {false, "UNKNOWN_75", nullptr}, - /* 0x76 */ {false, "REFLECT", "Generate reverse attack"}, - /* 0x77 */ {false, "UNKNOWN_77", nullptr}, - /* 0x78 */ {false, "ANY", nullptr}, // Treated as "any condition" in find functions - /* 0x79 */ {false, "UNKNOWN_79", nullptr}, - /* 0x7A */ {false, "UNKNOWN_7A", nullptr}, - /* 0x7B */ {false, "UNKNOWN_7B", nullptr}, - /* 0x7C */ {false, "UNKNOWN_7C", nullptr}, - /* 0x7D */ {false, "UNKNOWN_7D", nullptr}, + /* 0x00 */ {false, "NONE", nullptr}, + /* 0x01 */ {true, "AP_BOOST", "Temporarily increase AP by N"}, + /* 0x02 */ {false, "RAMPAGE", "Rampage"}, + /* 0x03 */ {true, "MULTI_STRIKE", "Duplicate attack N times"}, + /* 0x04 */ {true, "DAMAGE_MOD_1", "Set attack damage / AP to N after action cards applied (step 1)"}, + /* 0x05 */ {false, "IMMOBILE", "Give Immobile condition"}, + /* 0x06 */ {false, "HOLD", "Give Hold condition"}, + /* 0x07 */ {false, "UNKNOWN_07", nullptr}, + /* 0x08 */ {true, "TP_BOOST", "Add N TP temporarily during attack"}, + /* 0x09 */ {true, "GIVE_DAMAGE", "Cause direct N HP loss"}, + /* 0x0A */ {false, "GUOM", "Give Guom condition"}, + /* 0x0B */ {false, "PARALYZE", "Give Paralysis condition"}, + /* 0x0C */ {false, "UNKNOWN_0C", nullptr}, + /* 0x0D */ {false, "A_H_SWAP", "Swap AP and HP temporarily"}, + /* 0x0E */ {false, "PIERCE", "Attack SC directly even if they have items equipped"}, + /* 0x0F */ {false, "UNKNOWN_0F", nullptr}, + /* 0x10 */ {true, "HEAL", "Increase HP by N"}, + /* 0x11 */ {false, "RETURN_TO_HAND", "Return card to hand"}, + /* 0x12 */ {false, "UNKNOWN_12", nullptr}, + /* 0x13 */ {false, "UNKNOWN_13", nullptr}, + /* 0x14 */ {false, "ACID", "Give Acid condition"}, + /* 0x15 */ {false, "UNKNOWN_15", nullptr}, + /* 0x16 */ {true, "MIGHTY_KNUCKLE", "Temporarily increase AP by N, and set ATK dice to zero"}, + /* 0x17 */ {true, "UNIT_BLOW", "Temporarily increase AP by N * number of this card set within phase"}, + /* 0x18 */ {false, "CURSE", "Give Curse condition"}, + /* 0x19 */ {false, "COMBO_AP", "Temporarily increase AP by number of this card set within phase"}, + /* 0x1A */ {false, "PIERCE_RAMPAGE_BLOCK", "Block attack if Pierce/Rampage (?)"}, + /* 0x1B */ {false, "ABILITY_TRAP", "Temporarily disable opponent abilities"}, + /* 0x1C */ {false, "FREEZE", "Give Freeze condition"}, + /* 0x1D */ {false, "ANTI_ABNORMALITY_1", "Cure all conditions"}, + /* 0x1E */ {false, "UNKNOWN_1E", nullptr}, + /* 0x1F */ {false, "EXPLOSION", "Damage all SCs and FCs by number of this same card set * 2"}, + /* 0x20 */ {false, "UNKNOWN_20", nullptr}, + /* 0x21 */ {false, "UNKNOWN_21", nullptr}, + /* 0x22 */ {false, "UNKNOWN_22", nullptr}, + /* 0x23 */ {false, "RETURN_TO_DECK", "Cancel discard and move to bottom of deck instead"}, + /* 0x24 */ {false, "AERIAL", "Give Aerial status"}, + /* 0x25 */ {true, "AP_LOSS", "Make attacker temporarily lose N AP during defense"}, + /* 0x26 */ {true, "BONUS_FROM_LEADER", "Gain AP equal to the number of cards of type N on the field"}, + /* 0x27 */ {false, "FREE_MANEUVER", "Enable movement over occupied tiles"}, + /* 0x28 */ {false, "HASTE", "Make move actions free"}, + /* 0x29 */ {true, "CLONE", "Make setting this card free if at least one card of type N is already on the field"}, + /* 0x2A */ {true, "DEF_DISABLE_BY_COST", "Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive"}, + /* 0x2B */ {true, "FILIAL", "Increase controlling SC\'s HP by N when this card is destroyed"}, + /* 0x2C */ {true, "SNATCH", "Steal N EXP during attack"}, + /* 0x2D */ {true, "HAND_DISRUPTER", "Discard N cards from hand immediately"}, + /* 0x2E */ {false, "DROP", "Give Drop condition"}, + /* 0x2F */ {false, "ACTION_DISRUPTER", "Destroy all action cards used by attacker"}, + /* 0x30 */ {true, "SET_HP", "Set HP to N"}, + /* 0x31 */ {false, "NATIVE_SHIELD", "Block attacks from Native creatures"}, + /* 0x32 */ {false, "A_BEAST_SHIELD", "Block attacks from A.Beast creatures"}, + /* 0x33 */ {false, "MACHINE_SHIELD", "Block attacks from Machine creatures"}, + /* 0x34 */ {false, "DARK_SHIELD", "Block attacks from Dark creatures"}, + /* 0x35 */ {false, "SWORD_SHIELD", "Block attacks from Sword items"}, + /* 0x36 */ {false, "GUN_SHIELD", "Block attacks from Gun items"}, + /* 0x37 */ {false, "CANE_SHIELD", "Block attacks from Cane items"}, + /* 0x38 */ {false, "UNKNOWN_38", nullptr}, + /* 0x39 */ {false, "UNKNOWN_39", nullptr}, + /* 0x3A */ {false, "DEFENDER", "Make attacks go to setter of this card instead of original target"}, + /* 0x3B */ {false, "SURVIVAL_DECOYS", "Redirect damage for multi-sided attack"}, + /* 0x3C */ {true, "GIVE_OR_TAKE_EXP", "Give N EXP, or take if N is negative"}, + /* 0x3D */ {false, "UNKNOWN_3D", nullptr}, + /* 0x3E */ {false, "DEATH_COMPANION", "If this card has 1 or 2 HP, set its HP to N"}, + /* 0x3F */ {true, "EXP_DECOY", "If defender has EXP, lose EXP instead of getting damage when attacked"}, + /* 0x40 */ {true, "SET_MV", "Set MV to N"}, + /* 0x41 */ {true, "GROUP", "Temporarily increase AP by N * number of this card on field, excluding itself"}, + /* 0x42 */ {false, "BERSERK", "User of this card receives the same damage as target, and isn\'t helped by target\'s defense cards"}, + /* 0x43 */ {false, "GUARD_CREATURE", "Attacks on controlling SC damage this card instead"}, + /* 0x44 */ {false, "TECH", "Technique cards cost 1 fewer ATK point"}, + /* 0x45 */ {false, "BIG_SWING", "Increase all attacking ATK costs by 1"}, + /* 0x46 */ {false, "UNKNOWN_46", nullptr}, + /* 0x47 */ {false, "SHIELD_WEAPON", "Limit attacker\'s choice of target to guard items"}, + /* 0x48 */ {false, "ATK_DICE_BOOST", "Increase ATK dice roll by 1"}, + /* 0x49 */ {false, "UNKNOWN_49", nullptr}, + /* 0x4A */ {false, "MAJOR_PIERCE", "If SC has over half of max HP, attacks target SC instead of equipped items"}, + /* 0x4B */ {false, "HEAVY_PIERCE", "If SC has 3 or more items equipped, attacks target SC instead of equipped items"}, + /* 0x4C */ {false, "MAJOR_RAMPAGE", "If SC has over half of max HP, attacks target SC and all equipped items"}, + /* 0x4D */ {false, "HEAVY_RAMPAGE", "If SC has 3 or more items equipped, attacks target SC and all equipped items"}, + /* 0x4E */ {true, "AP_GROWTH", "Permanently increase AP by N"}, + /* 0x4F */ {true, "TP_GROWTH", "Permanently increase TP by N"}, + /* 0x50 */ {true, "REBORN", "If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded"}, + /* 0x51 */ {true, "COPY", "Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent\'s values"}, + /* 0x52 */ {false, "UNKNOWN_52", nullptr}, + /* 0x53 */ {true, "MISC_GUARDS", "Add N to card\'s defense value"}, + /* 0x54 */ {true, "AP_OVERRIDE", "Set AP to N temporarily"}, + /* 0x55 */ {true, "TP_OVERRIDE", "Set TP to N temporarily"}, + /* 0x56 */ {false, "RETURN", "Return card to hand on destruction instead of discarding"}, + /* 0x57 */ {false, "A_T_SWAP_PERM", "Permanently swap AP and TP"}, + /* 0x58 */ {false, "A_H_SWAP_PERM", "Permanently swap AP and HP"}, + /* 0x59 */ {true, "SLAYERS_ASSASSINS", "Temporarily increase AP during attack"}, + /* 0x5A */ {false, "ANTI_ABNORMALITY_2", "Remove all conditions"}, + /* 0x5B */ {false, "FIXED_RANGE", "Use SC\'s range instead of weapon or attack card ranges"}, + /* 0x5C */ {false, "ELUDE", "SC does not lose HP when equipped items are destroyed"}, + /* 0x5D */ {false, "PARRY", "Forward attack to a random FC within one tile of original target, excluding attacker and original target"}, + /* 0x5E */ {false, "BLOCK_ATTACK", "Completely block attack"}, + /* 0x5F */ {false, "UNKNOWN_5F", nullptr}, + /* 0x60 */ {false, "UNKNOWN_60", nullptr}, + /* 0x61 */ {true, "COMBO_TP", "Gain TP equal to the number of cards of type N on the field"}, + /* 0x62 */ {true, "MISC_AP_BONUSES", "Temporarily increase AP by N"}, + /* 0x63 */ {true, "MISC_TP_BONUSES", "Temporarily increase TP by N"}, + /* 0x64 */ {false, "UNKNOWN_64", nullptr}, + /* 0x65 */ {true, "MISC_DEFENSE_BONUSES", "Decrease damage by N"}, + /* 0x66 */ {true, "MOSTLY_HALFGUARDS", "Reduce damage from incoming attack by N"}, + /* 0x67 */ {false, "PERIODIC_FIELD", "Swap immunity to tech or physical attacks"}, + /* 0x68 */ {false, "FC_LIMIT_BY_COUNT", "Change FC limit from 8 ATK points total to 4 FCs total"}, + /* 0x69 */ {false, "UNKNOWN_69", nullptr}, + /* 0x6A */ {true, "MV_BONUS", "Increase MV by N"}, + /* 0x6B */ {true, "FORWARD_DAMAGE", "Give N damage back to attacker during defense (?) (TODO)"}, + /* 0x6C */ {true, "WEAK_SPOT_INFLUENCE", "Temporarily decrease AP by N"}, + /* 0x6D */ {true, "DAMAGE_MODIFIER_2", "Set attack damage / AP after action cards applied (step 2)"}, + /* 0x6E */ {true, "WEAK_HIT_BLOCK", "Block all attacks of N damage or less"}, + /* 0x6F */ {true, "AP_SILENCE", "Temporarily decrease AP of opponent by N"}, + /* 0x70 */ {true, "TP_SILENCE", "Temporarily decrease TP of opponent by N"}, + /* 0x71 */ {false, "A_T_SWAP", "Temporarily swap AP and TP"}, + /* 0x72 */ {true, "HALFGUARD", "Halve damage from attacks that would inflict N or more damage"}, + /* 0x73 */ {false, "UNKNOWN_73", nullptr}, + /* 0x74 */ {true, "RAMPAGE_AP_LOSS", "Temporarily reduce AP by N"}, + /* 0x75 */ {false, "UNKNOWN_75", nullptr}, + /* 0x76 */ {false, "REFLECT", "Generate reverse attack"}, + /* 0x77 */ {false, "UNKNOWN_77", nullptr}, + /* 0x78 */ {false, "ANY", nullptr}, // Treated as "any condition" in find functions + /* 0x79 */ {false, "UNKNOWN_79", nullptr}, + /* 0x7A */ {false, "UNKNOWN_7A", nullptr}, + /* 0x7B */ {false, "UNKNOWN_7B", nullptr}, + /* 0x7C */ {false, "UNKNOWN_7C", nullptr}, + /* 0x7D */ {false, "UNKNOWN_7D", nullptr}, }); const char* name_for_condition_type(ConditionType cond_type) { @@ -445,8 +438,6 @@ const char* name_for_condition_type(ConditionType cond_type) { } } - - const char* name_for_action_subphase(ActionSubphase subphase) { switch (subphase) { case ActionSubphase::ATTACK: @@ -460,8 +451,6 @@ const char* name_for_action_subphase(ActionSubphase subphase) { } } - - void CardDefinition::Stat::decode_code() { this->type = static_cast(this->code / 1000); int16_t value = this->code - (this->type * 1000); @@ -512,8 +501,6 @@ string CardDefinition::Stat::str() const { } } - - bool CardDefinition::Effect::is_empty() const { return (this->effect_num == 0 && this->type == ConditionType::NONE && @@ -588,7 +575,8 @@ string CardDefinition::Effect::str() const { cmd_str += ':'; cmd_str += name; } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } string expr_str = this->expr; if (!expr_str.empty()) { @@ -599,12 +587,10 @@ string CardDefinition::Effect::str() const { string arg2str = this->str_for_arg(this->arg2); string arg3str = this->str_for_arg(this->arg3); return string_printf("(cmd=%s%s, when=%02hhX, arg1=%s, arg2=%s, arg3=%s, cond=%02hhX, a2=%02hhX)", - cmd_str.c_str(), expr_str.c_str(), this->when, arg1str.data(), - arg2str.data(), arg3str.data(), static_cast(this->apply_criterion), this->unknown_a2); + cmd_str.c_str(), expr_str.c_str(), this->when, arg1str.data(), + arg2str.data(), arg3str.data(), static_cast(this->apply_criterion), this->unknown_a2); } - - bool CardDefinition::is_sc() const { return (this->type == CardType::HUNTERS_SC) || (this->type == CardType::ARKZ_SC); } @@ -614,8 +600,7 @@ bool CardDefinition::is_fc() const { } bool CardDefinition::is_named_android_sc() const { - static const unordered_set TARGET_IDS({ - 0x0005, 0x0007, 0x0110, 0x0113, 0x0114, 0x0117, 0x011B, 0x011F}); + static const unordered_set TARGET_IDS({0x0005, 0x0007, 0x0110, 0x0113, 0x0114, 0x0117, 0x011B, 0x011F}); return TARGET_IDS.count(this->card_id); } @@ -636,8 +621,6 @@ CardClass CardDefinition::card_class() const { return static_cast(this->be_card_class.load()); } - - void CardDefinition::decode_range() { // If the cell representing the FC is nonzero, the card has a range from a // list of constants. Otherwise, its range is already defined in the range @@ -695,20 +678,20 @@ void CardDefinition::decode_range() { string name_for_rarity(CardRarity rarity) { static const vector names({ - "N1", - "R1", - "S", - "E", - "N2", - "N3", - "N4", - "R2", - "R3", - "R4", - "SS", - "D1", - "D2", - "INVIS", + "N1", + "R1", + "S", + "E", + "N2", + "N3", + "N4", + "R2", + "R3", + "R4", + "SS", + "D1", + "D2", + "INVIS", }); try { return names.at(static_cast(rarity) - 1); @@ -719,16 +702,16 @@ string name_for_rarity(CardRarity rarity) { string name_for_target_mode(TargetMode target_mode) { static const vector names({ - "NONE", - "SINGLE", - "MULTI", - "SELF", - "TEAM", - "ALL", - "MULTI-ALLY", - "ALL-ALLY", - "ALL-ATTACK", - "OWN-FCS", + "NONE", + "SINGLE", + "MULTI", + "SELF", + "TEAM", + "ALL", + "MULTI-ALLY", + "ALL-ALLY", + "ALL-ATTACK", + "OWN-FCS", }); try { return names.at(static_cast(target_mode)); @@ -837,8 +820,6 @@ string CardDefinition::str() const { effects_str.c_str()); } - - Rules::Rules() { this->clear(); } @@ -920,7 +901,7 @@ string Rules::str() const { break; default: tokens.emplace_back(string_printf("hp_type=(%02hhX)", - static_cast(this->hp_type))); + static_cast(this->hp_type))); break; } @@ -938,7 +919,7 @@ string Rules::str() const { break; default: tokens.emplace_back(string_printf("dice_exchange=(%02hhX)", - static_cast(this->dice_exchange_mode))); + static_cast(this->dice_exchange_mode))); break; } tokens.emplace_back(string_printf("dice_boost=%s", this->disable_dice_boost ? "DISABLED" : "ENABLED")); @@ -961,7 +942,7 @@ string Rules::str() const { break; default: tokens.emplace_back(string_printf("allowed_cards=(%02hhX)", - static_cast(this->allowed_cards))); + static_cast(this->allowed_cards))); break; } tokens.emplace_back(string_printf("assist_cards=%s", this->no_assist_cards ? "DISALLOWED" : "ALLOWED")); @@ -974,8 +955,6 @@ string Rules::str() const { return "Rules[" + join(tokens, ", ") + "]"; } - - StateFlags::StateFlags() { this->clear(); } @@ -1028,8 +1007,6 @@ void StateFlags::clear_FF() { this->client_sc_card_types.clear(CardType::INVALID_FF); } - - string MapDefinition::str(const DataIndex* data_index) const { deque lines; auto add_map = [&](const parray, 0x10>& tiles) { @@ -1043,13 +1020,14 @@ string MapDefinition::str(const DataIndex* data_index) const { }; lines.emplace_back(string_printf("Map %08" PRIX32 ": %hhux%hhu", - this->map_number.load(), this->width, this->height)); + this->map_number.load(), this->width, this->height)); lines.emplace_back(string_printf(" a1=%08" PRIX32, this->unknown_a1.load())); lines.emplace_back(string_printf(" environment_number=%02hhX", this->environment_number)); lines.emplace_back(string_printf(" num_alt_maps=%02hhX", this->num_alt_maps)); lines.emplace_back(" tiles:"); add_map(this->map_tiles); - lines.emplace_back(string_printf(" start_tile_definitions=[1p=%02hhX 2p=%02hhX,%02hhX 3p=%02hhX,%02hhX,%02hhX], [1p=%02hhX 2p=%02hhX,%02hhX 3p=%02hhX,%02hhX,%02hhX]", + lines.emplace_back(string_printf( + " start_tile_definitions=[1p=%02hhX 2p=%02hhX,%02hhX 3p=%02hhX,%02hhX,%02hhX], [1p=%02hhX 2p=%02hhX,%02hhX 3p=%02hhX,%02hhX,%02hhX]", this->start_tile_definitions[0][0], this->start_tile_definitions[0][1], this->start_tile_definitions[0][2], this->start_tile_definitions[0][3], this->start_tile_definitions[0][4], this->start_tile_definitions[0][5], @@ -1062,7 +1040,8 @@ string MapDefinition::str(const DataIndex* data_index) const { add_map(this->alt_maps1[w][z]); } for (size_t w = 0; w < 2; w++) { - lines.emplace_back(string_printf(" alt tiles a3 %zu/%zu=%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", z, w, + lines.emplace_back(string_printf( + " alt tiles a3 %zu/%zu=%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", z, w, this->alt_maps_unknown_a3[w][z][0x00].load(), this->alt_maps_unknown_a3[w][z][0x01].load(), this->alt_maps_unknown_a3[w][z][0x02].load(), this->alt_maps_unknown_a3[w][z][0x03].load(), this->alt_maps_unknown_a3[w][z][0x04].load(), this->alt_maps_unknown_a3[w][z][0x05].load(), @@ -1076,7 +1055,8 @@ string MapDefinition::str(const DataIndex* data_index) const { } for (size_t w = 0; w < 3; w++) { for (size_t z = 0; z < 0x24; z += 3) { - lines.emplace_back(string_printf(" a4[%zu][0x%02zX:0x%02zX]=%g %g %g", w, z, z + 3, + lines.emplace_back(string_printf( + " a4[%zu][0x%02zX:0x%02zX]=%g %g %g", w, z, z + 3, this->unknown_a4[w][z + 0].load(), this->unknown_a4[w][z + 1].load(), this->unknown_a4[w][z + 2].load())); @@ -1085,16 +1065,19 @@ string MapDefinition::str(const DataIndex* data_index) const { lines.emplace_back(" modification tiles:"); add_map(this->modification_tiles); for (size_t z = 0; z < 0x70; z += 0x10) { - lines.emplace_back(string_printf(" a5[0x%02zX:0x%02zX]=%02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX", z, z + 0x10, + lines.emplace_back(string_printf( + " a5[0x%02zX:0x%02zX]=%02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX", z, z + 0x10, this->unknown_a5[z + 0x00], this->unknown_a5[z + 0x01], this->unknown_a5[z + 0x02], this->unknown_a5[z + 0x03], this->unknown_a5[z + 0x04], this->unknown_a5[z + 0x05], this->unknown_a5[z + 0x06], this->unknown_a5[z + 0x07], this->unknown_a5[z + 0x08], this->unknown_a5[z + 0x09], this->unknown_a5[z + 0x0A], this->unknown_a5[z + 0x0B], this->unknown_a5[z + 0x0C], this->unknown_a5[z + 0x0D], this->unknown_a5[z + 0x0E], this->unknown_a5[z + 0x0F])); } - lines.emplace_back(string_printf(" a5[0x70:0x74]=%02hhX %02hhX %02hhX %02hhX", + lines.emplace_back(string_printf( + " a5[0x70:0x74]=%02hhX %02hhX %02hhX %02hhX", this->unknown_a5[0x70], this->unknown_a5[0x71], this->unknown_a5[0x72], this->unknown_a5[0x73])); lines.emplace_back(" default_rules: " + this->default_rules.str()); - lines.emplace_back(string_printf(" a6=%02hhX %02hhX %02hhX %02hhX", + lines.emplace_back(string_printf( + " a6=%02hhX %02hhX %02hhX %02hhX", this->unknown_a6[0], this->unknown_a6[1], this->unknown_a6[2], this->unknown_a6[3])); lines.emplace_back(" name: " + string(this->name)); lines.emplace_back(" location_name: " + string(this->location_name)); @@ -1103,21 +1086,25 @@ string MapDefinition::str(const DataIndex* data_index) const { lines.emplace_back(string_printf(" map_xy: %hu %hu", this->map_x.load(), this->map_y.load())); for (size_t z = 0; z < 3; z++) { lines.emplace_back(string_printf(" npc_chars[%zu]:", z)); - lines.emplace_back(string_printf(" a1=%04hX %04hX", + lines.emplace_back(string_printf( + " a1=%04hX %04hX", this->npc_chars[z].unknown_a1[0].load(), this->npc_chars[z].unknown_a1[1].load())); - lines.emplace_back(string_printf(" a2=%02hX %02hX %02hX %02hX", + lines.emplace_back(string_printf( + " a2=%02hX %02hX %02hX %02hX", this->npc_chars[z].unknown_a2[0], this->npc_chars[z].unknown_a2[1], this->npc_chars[z].unknown_a2[2], this->npc_chars[z].unknown_a2[3])); lines.emplace_back(" name: " + string(this->npc_chars[z].name)); for (size_t w = 0; w < 0x78; w += 0x08) { - lines.emplace_back(string_printf(" a3[0x%02zX:0x%02zX]=%04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX", + lines.emplace_back(string_printf( + " a3[0x%02zX:0x%02zX]=%04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX", w, w + 0x08, this->npc_chars[z].unknown_a3[w + 0x00].load(), this->npc_chars[z].unknown_a3[w + 0x01].load(), this->npc_chars[z].unknown_a3[w + 0x02].load(), this->npc_chars[z].unknown_a3[w + 0x03].load(), this->npc_chars[z].unknown_a3[w + 0x04].load(), this->npc_chars[z].unknown_a3[w + 0x05].load(), this->npc_chars[z].unknown_a3[w + 0x06].load(), this->npc_chars[z].unknown_a3[w + 0x07].load())); } - lines.emplace_back(string_printf(" a3[0x78:0x7E]=%04hX %04hX %04hX %04hX %04hX %04hX", + lines.emplace_back(string_printf( + " a3[0x78:0x7E]=%04hX %04hX %04hX %04hX %04hX %04hX", this->npc_chars[z].unknown_a3[0x78].load(), this->npc_chars[z].unknown_a3[0x79].load(), this->npc_chars[z].unknown_a3[0x7A].load(), this->npc_chars[z].unknown_a3[0x7B].load(), this->npc_chars[z].unknown_a3[0x7C].load(), this->npc_chars[z].unknown_a3[0x7D].load())); @@ -1129,7 +1116,8 @@ string MapDefinition::str(const DataIndex* data_index) const { if (data_index) { try { entry = data_index->definition_for_card_id(card_id); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } if (entry) { string name = entry->def.en_name; @@ -1152,7 +1140,7 @@ string MapDefinition::str(const DataIndex* data_index) const { } lines.emplace_back(" a7a=" + format_data_string(this->unknown_a7_a.data(), this->unknown_a7_a.bytes())); lines.emplace_back(string_printf(" a7b=[%08" PRIX32 " %08" PRIX32 " %08" PRIX32 "]", - this->unknown_a7_b[0].load(), this->unknown_a7_b[1].load(), this->unknown_a7_b[2].load())); + this->unknown_a7_b[0].load(), this->unknown_a7_b[1].load(), this->unknown_a7_b[2].load())); if (this->before_message[0]) { lines.emplace_back(" before_message: " + string(this->before_message)); } @@ -1168,7 +1156,8 @@ string MapDefinition::str(const DataIndex* data_index) const { if (data_index) { try { entry = data_index->definition_for_card_id(card_id); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } if (entry) { string name = entry->def.en_name; @@ -1178,35 +1167,35 @@ string MapDefinition::str(const DataIndex* data_index) const { } } lines.emplace_back(string_printf(" a9=[%08" PRIX32 " %08" PRIX32 " %04hX %04hX]", - this->unknown_a9_a.load(), this->unknown_a9_b.load(), this->unknown_a9_c.load(), this->unknown_a9_d.load())); + this->unknown_a9_a.load(), this->unknown_a9_b.load(), this->unknown_a9_c.load(), this->unknown_a9_d.load())); lines.emplace_back(string_printf(" a10=%02hhX", this->unknown_a10)); lines.emplace_back(string_printf(" cyber_block_type=%02hhX", this->cyber_block_type)); lines.emplace_back(string_printf(" a11=%02hhX%02hhX", this->unknown_a11[0], this->unknown_a11[1])); static const array sc_card_entry_names = { - "00 (Guykild; 0005)", - "01 (Kylria; 0006)", - "02 (Saligun; 0110)", - "03 (Relmitos; 0111)", - "04 (Kranz; 0002)", - "05 (Sil'fer; 0004)", - "06 (Ino'lis; 0003)", - "07 (Viviana; 0112)", - "08 (Teifu; 0113)", - "09 (Orland; 0001)", - "0A (Stella; 0114)", - "0B (Glustar; 0115)", - "0C (Hyze; 0117)", - "0D (Rufina; 0118)", - "0E (Peko; 0119)", - "0F (Creinu; 011A)", - "10 (Reiz; 011B)", - "11 (Lura; 0007)", - "12 (Break; 0008)", - "13 (Rio; 011C)", - "14 (Endu; 0116)", - "15 (Memoru; 011D)", - "16 (K.C.; 011E)", - "17 (Ohgun; 011F)", + "00 (Guykild; 0005)", + "01 (Kylria; 0006)", + "02 (Saligun; 0110)", + "03 (Relmitos; 0111)", + "04 (Kranz; 0002)", + "05 (Sil'fer; 0004)", + "06 (Ino'lis; 0003)", + "07 (Viviana; 0112)", + "08 (Teifu; 0113)", + "09 (Orland; 0001)", + "0A (Stella; 0114)", + "0B (Glustar; 0115)", + "0C (Hyze; 0117)", + "0D (Rufina; 0118)", + "0E (Peko; 0119)", + "0F (Creinu; 011A)", + "10 (Reiz; 011B)", + "11 (Lura; 0007)", + "12 (Break; 0008)", + "13 (Rio; 011C)", + "14 (Endu; 0116)", + "15 (Memoru; 011D)", + "16 (K.C.; 011E)", + "17 (Ohgun; 011F)", }; string unavailable_sc_cards = " unavailable_sc_cards=["; for (size_t z = 0; z < 0x18; z++) { @@ -1338,10 +1327,8 @@ bool Rules::check_and_reset_invalid_fields() { return ret; } - - DataIndex::DataIndex(const string& directory, uint32_t behavior_flags) - : behavior_flags(behavior_flags) { + : behavior_flags(behavior_flags) { unordered_map> card_tags; unordered_map card_text; @@ -1487,10 +1474,12 @@ DataIndex::DataIndex(const string& directory, uint32_t behavior_flags) if (this->behavior_flags & BehaviorFlag::LOAD_CARD_TEXT) { try { entry->text = move(card_text.at(defs[x].card_id)); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { entry->debug_tags = move(card_tags.at(defs[x].card_id)); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } } @@ -1533,13 +1522,13 @@ DataIndex::DataIndex(const string& directory, uint32_t behavior_flags) this->maps_by_name.emplace(entry->map.name, entry); string name = entry->map.name; static_game_data_log.info("Indexed Episode 3 %s %s (%08" PRIX32 "; %s)", - is_quest ? "online quest" : "free battle map", - filename.c_str(), entry->map.map_number.load(), name.c_str()); + is_quest ? "online quest" : "free battle map", + filename.c_str(), entry->map.map_number.load(), name.c_str()); } } catch (const exception& e) { static_game_data_log.warning("Failed to index Episode 3 map %s: %s", - filename.c_str(), e.what()); + filename.c_str(), e.what()); } } }; @@ -1567,10 +1556,12 @@ DataIndex::DataIndex(const string& directory, uint32_t behavior_flags) } DataIndex::MapEntry::MapEntry(const MapDefinition& map, bool is_quest) - : map(map), is_quest(is_quest) { } + : map(map), + is_quest(is_quest) {} DataIndex::MapEntry::MapEntry(const string& compressed, bool is_quest) - : is_quest(is_quest), compressed_data(compressed) { + : is_quest(is_quest), + compressed_data(compressed) { string decompressed = prs_decompress(this->compressed_data); if (decompressed.size() != sizeof(MapDefinition)) { throw runtime_error(string_printf( @@ -1673,7 +1664,7 @@ const string& DataIndex::get_compressed_map_list() const { } size_t decompressed_size = sizeof(header) + entries_w.size() + strings_w.size(); static_game_data_log.info("Generated Episode 3 compressed map list (0x%zX -> 0x%zX bytes)", - decompressed_size, this->compressed_map_list.size()); + decompressed_size, this->compressed_map_list.size()); } return this->compressed_map_list; } @@ -1711,8 +1702,6 @@ shared_ptr DataIndex::random_com_deck() const { return this->com_decks[random_object() % this->com_decks.size()]; } - - void PlayerConfig::decrypt() { if (!this->is_encrypted) { return; @@ -1740,6 +1729,4 @@ void PlayerConfig::encrypt(uint8_t basis) { this->basis = basis; } - - } // namespace Episode3 diff --git a/src/Episode3/DataIndex.hh b/src/Episode3/DataIndex.hh index 56748eb3..6a5d2b95 100644 --- a/src/Episode3/DataIndex.hh +++ b/src/Episode3/DataIndex.hh @@ -2,42 +2,36 @@ #include -#include #include -#include #include -#include #include #include +#include +#include +#include #include "../Text.hh" namespace Episode3 { - - // The comment in Server.hh does not apply to this file (and DataIndex.cc). // Except for the Location structure, these structures and functions are not // based on Sega's original implementation. class DataIndex; - - enum BehaviorFlag { - SKIP_DECK_VERIFY = 0x00000001, - IGNORE_CARD_COUNTS = 0x00000002, - SKIP_D1_D2_REPLACE = 0x00000004, - DISABLE_TIME_LIMITS = 0x00000008, + SKIP_DECK_VERIFY = 0x00000001, + IGNORE_CARD_COUNTS = 0x00000002, + SKIP_D1_D2_REPLACE = 0x00000004, + DISABLE_TIME_LIMITS = 0x00000008, ENABLE_STATUS_MESSAGES = 0x00000010, - LOAD_CARD_TEXT = 0x00000020, - ENABLE_RECORDING = 0x00000040, - DISABLE_MASKING = 0x00000080, - DISABLE_INTERFERENCE = 0x00000100, + LOAD_CARD_TEXT = 0x00000020, + ENABLE_RECORDING = 0x00000040, + DISABLE_MASKING = 0x00000080, + DISABLE_INTERFERENCE = 0x00000100, }; - - enum class StatSwapType : uint8_t { NONE = 0, A_T_SWAP = 1, @@ -99,54 +93,54 @@ enum class CriterionCode : uint8_t { }; enum class CardRarity : uint8_t { - N1 = 0x01, - R1 = 0x02, - S = 0x03, - E = 0x04, - N2 = 0x05, - N3 = 0x06, - N4 = 0x07, - R2 = 0x08, - R3 = 0x09, - R4 = 0x0A, - SS = 0x0B, - D1 = 0x0C, - D2 = 0x0D, + N1 = 0x01, + R1 = 0x02, + S = 0x03, + E = 0x04, + N2 = 0x05, + N3 = 0x06, + N4 = 0x07, + R2 = 0x08, + R3 = 0x09, + R4 = 0x0A, + SS = 0x0B, + D1 = 0x0C, + D2 = 0x0D, INVIS = 0x0E, }; enum class CardType : uint8_t { HUNTERS_SC = 0x00, - ARKZ_SC = 0x01, - ITEM = 0x02, - CREATURE = 0x03, - ACTION = 0x04, - ASSIST = 0x05, + ARKZ_SC = 0x01, + ITEM = 0x02, + CREATURE = 0x03, + ACTION = 0x04, + ASSIST = 0x05, INVALID_FF = 0xFF, END_CARD_LIST = 0xFF, }; enum class CardClass : uint16_t { - HU_SC = 0x0000, - RA_SC = 0x0001, - FO_SC = 0x0002, - NATIVE_CREATURE = 0x000A, - A_BEAST_CREATURE = 0x000B, - MACHINE_CREATURE = 0x000C, - DARK_CREATURE = 0x000D, - GUARD_ITEM = 0x0015, - MAG_ITEM = 0x0017, - SWORD_ITEM = 0x0018, - GUN_ITEM = 0x0019, - CANE_ITEM = 0x001A, - ATTACK_ACTION = 0x001E, - DEFENSE_ACTION = 0x001F, - TECH = 0x0020, - PHOTON_BLAST = 0x0021, + HU_SC = 0x0000, + RA_SC = 0x0001, + FO_SC = 0x0002, + NATIVE_CREATURE = 0x000A, + A_BEAST_CREATURE = 0x000B, + MACHINE_CREATURE = 0x000C, + DARK_CREATURE = 0x000D, + GUARD_ITEM = 0x0015, + MAG_ITEM = 0x0017, + SWORD_ITEM = 0x0018, + GUN_ITEM = 0x0019, + CANE_ITEM = 0x001A, + ATTACK_ACTION = 0x001E, + DEFENSE_ACTION = 0x001F, + TECH = 0x0020, + PHOTON_BLAST = 0x0021, CONNECT_ONLY_ATTACK_ACTION = 0x0022, - BOSS_ATTACK_ACTION = 0x0023, - BOSS_TECH = 0x0024, - ASSIST = 0x0028, + BOSS_ATTACK_ACTION = 0x0023, + BOSS_TECH = 0x0024, + ASSIST = 0x0028, }; bool card_class_is_tech_like(CardClass cc); @@ -165,216 +159,216 @@ enum class TargetMode : uint8_t { }; enum class ConditionType : uint8_t { - NONE = 0x00, - AP_BOOST = 0x01, // Temporarily increase AP by N - RAMPAGE = 0x02, - MULTI_STRIKE = 0x03, // Duplicate attack N times - DAMAGE_MOD_1 = 0x04, // Set attack damage / AP to N after action cards applied (step 1) - IMMOBILE = 0x05, // Give Immobile condition - HOLD = 0x06, // Give Hold condition - UNKNOWN_07 = 0x07, - TP_BOOST = 0x08, // Add N TP temporarily during attack - GIVE_DAMAGE = 0x09, // Cause direct N HP loss - GUOM = 0x0A, // Give Guom condition - PARALYZE = 0x0B, // Give Paralysis condition - UNKNOWN_0C = 0x0C, // Swap AP and TP temporarily (presumably) - A_H_SWAP = 0x0D, // Swap AP and HP temporarily - PIERCE = 0x0E, // Attack SC directly even if they have items equipped - UNKNOWN_0F = 0x0F, - HEAL = 0x10, // Increase HP by N - RETURN_TO_HAND = 0x11, // Return card to hand - UNKNOWN_12 = 0x12, - UNKNOWN_13 = 0x13, - ACID = 0x14, // Give Acid condition - UNKNOWN_15 = 0x15, - MIGHTY_KNUCKLE = 0x16, // Temporarily increase AP by N, and set ATK dice to zero - UNIT_BLOW = 0x17, // Temporarily increase AP by N * number of this card set within phase - CURSE = 0x18, // Give Curse condition - COMBO_AP = 0x19, // Temporarily increase AP by number of this card set within phase + NONE = 0x00, + AP_BOOST = 0x01, // Temporarily increase AP by N + RAMPAGE = 0x02, + MULTI_STRIKE = 0x03, // Duplicate attack N times + DAMAGE_MOD_1 = 0x04, // Set attack damage / AP to N after action cards applied (step 1) + IMMOBILE = 0x05, // Give Immobile condition + HOLD = 0x06, // Give Hold condition + UNKNOWN_07 = 0x07, + TP_BOOST = 0x08, // Add N TP temporarily during attack + GIVE_DAMAGE = 0x09, // Cause direct N HP loss + GUOM = 0x0A, // Give Guom condition + PARALYZE = 0x0B, // Give Paralysis condition + UNKNOWN_0C = 0x0C, // Swap AP and TP temporarily (presumably) + A_H_SWAP = 0x0D, // Swap AP and HP temporarily + PIERCE = 0x0E, // Attack SC directly even if they have items equipped + UNKNOWN_0F = 0x0F, + HEAL = 0x10, // Increase HP by N + RETURN_TO_HAND = 0x11, // Return card to hand + UNKNOWN_12 = 0x12, + UNKNOWN_13 = 0x13, + ACID = 0x14, // Give Acid condition + UNKNOWN_15 = 0x15, + MIGHTY_KNUCKLE = 0x16, // Temporarily increase AP by N, and set ATK dice to zero + UNIT_BLOW = 0x17, // Temporarily increase AP by N * number of this card set within phase + CURSE = 0x18, // Give Curse condition + COMBO_AP = 0x19, // Temporarily increase AP by number of this card set within phase PIERCE_RAMPAGE_BLOCK = 0x1A, // Block attack if Pierce/Rampage - ABILITY_TRAP = 0x1B, // Temporarily disable opponent abilities - FREEZE = 0x1C, // Give Freeze condition - ANTI_ABNORMALITY_1 = 0x1D, // Cure all abnormal conditions - UNKNOWN_1E = 0x1E, - EXPLOSION = 0x1F, // Damage all SCs and FCs by number of this same card set * 2 - UNKNOWN_20 = 0x20, - UNKNOWN_21 = 0x21, - UNKNOWN_22 = 0x22, - RETURN_TO_DECK = 0x23, // Cancel discard and move to bottom of deck instead - AERIAL = 0x24, // Give Aerial status - AP_LOSS = 0x25, // Make attacker temporarily lose N AP during defense - BONUS_FROM_LEADER = 0x26, // Gain AP equal to the number of cards of type N on the field - FREE_MANEUVER = 0x27, // Enable movement over occupied tiles - HASTE = 0x28, // Multiply all move action costs by expr (which may be zero) - CLONE = 0x29, // Make setting this card free if at least one card of type N is already on the field - DEF_DISABLE_BY_COST = 0x2A, // Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive - FILIAL = 0x2B, // Increase controlling SC's HP by N when this card is destroyed - SNATCH = 0x2C, // Steal N EXP during attack - HAND_DISRUPTER = 0x2D, // Discard N cards from hand immediately - DROP = 0x2E, // Give Drop condition - ACTION_DISRUPTER = 0x2F, // Destroy all action cards used by attacker - SET_HP = 0x30, // Set HP to N - NATIVE_SHIELD = 0x31, // Block attacks from Native creatures - A_BEAST_SHIELD = 0x32, // Block attacks from A.Beast creatures - MACHINE_SHIELD = 0x33, // Block attacks from Machine creatures - DARK_SHIELD = 0x34, // Block attacks from Dark creatures - SWORD_SHIELD = 0x35, // Block attacks from Sword items - GUN_SHIELD = 0x36, // Block attacks from Gun items - CANE_SHIELD = 0x37, // Block attacks from Cane items - UNKNOWN_38 = 0x38, - UNKNOWN_39 = 0x39, - DEFENDER = 0x3A, // Make attacks go to setter of this card instead of original target - SURVIVAL_DECOYS = 0x3B, // Redirect damage for multi-sided attack - GIVE_OR_TAKE_EXP = 0x3C, // Give N EXP, or take if N is negative - UNKNOWN_3D = 0x3D, - DEATH_COMPANION = 0x3E, // If this card has 1 or 2 HP, set its HP to N - EXP_DECOY = 0x3F, // If defender has EXP, lose EXP instead of getting damage when attacked - SET_MV = 0x40, // Set MV to N - GROUP = 0x41, // Temporarily increase AP by N * number of this card on field, excluding itself - BERSERK = 0x42, // User of this card receives the same damage as target, and isn't helped by target's defense cards - GUARD_CREATURE = 0x43, // Attacks on controlling SC damage this card instead - TECH = 0x44, // Technique cards cost 1 fewer ATK point - BIG_SWING = 0x45, // Increase all attacking ATK costs by 1 - UNKNOWN_46 = 0x46, - SHIELD_WEAPON = 0x47, // Limit attacker's choice of target to guard items - ATK_DICE_BOOST = 0x48, // Increase ATK dice roll by 1 - UNKNOWN_49 = 0x49, - MAJOR_PIERCE = 0x4A, // If SC has over half of max HP, attacks target SC instead of equipped items - HEAVY_PIERCE = 0x4B, // If SC has 3 or more items equipped, attacks target SC instead of equipped items - MAJOR_RAMPAGE = 0x4C, // If SC has over half of max HP, attacks target SC and all equipped items - HEAVY_RAMPAGE = 0x4D, // If SC has 3 or more items equipped, attacks target SC and all equipped items - AP_GROWTH = 0x4E, // Permanently increase AP by N - TP_GROWTH = 0x4F, // Permanently increase TP by N - REBORN = 0x50, // If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded - COPY = 0x51, // Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent's values - UNKNOWN_52 = 0x52, - MISC_GUARDS = 0x53, // Add N to card's defense value - AP_OVERRIDE = 0x54, // Set AP to N temporarily - TP_OVERRIDE = 0x55, // Set TP to N temporarily - RETURN = 0x56, // Return card to hand on destruction instead of discarding - A_T_SWAP_PERM = 0x57, // Permanently swap AP and TP - A_H_SWAP_PERM = 0x58, // Permanently swap AP and HP - SLAYERS_ASSASSINS = 0x59, // Temporarily increase AP during attack - ANTI_ABNORMALITY_2 = 0x5A, // Remove all conditions - FIXED_RANGE = 0x5B, // Use SC's range instead of weapon or attack card ranges - ELUDE = 0x5C, // SC does not lose HP when equipped items are destroyed - PARRY = 0x5D, // Forward attack to a random FC within one tile of original target, excluding attacker and original target - BLOCK_ATTACK = 0x5E, // Completely block attack - UNKNOWN_5F = 0x5F, - UNKNOWN_60 = 0x60, - COMBO_TP = 0x61, // Gain TP equal to the number of cards of type N on the field - MISC_AP_BONUSES = 0x62, // Temporarily increase AP by N - MISC_TP_BONUSES = 0x63, // Temporarily increase TP by N - UNKNOWN_64 = 0x64, + ABILITY_TRAP = 0x1B, // Temporarily disable opponent abilities + FREEZE = 0x1C, // Give Freeze condition + ANTI_ABNORMALITY_1 = 0x1D, // Cure all abnormal conditions + UNKNOWN_1E = 0x1E, + EXPLOSION = 0x1F, // Damage all SCs and FCs by number of this same card set * 2 + UNKNOWN_20 = 0x20, + UNKNOWN_21 = 0x21, + UNKNOWN_22 = 0x22, + RETURN_TO_DECK = 0x23, // Cancel discard and move to bottom of deck instead + AERIAL = 0x24, // Give Aerial status + AP_LOSS = 0x25, // Make attacker temporarily lose N AP during defense + BONUS_FROM_LEADER = 0x26, // Gain AP equal to the number of cards of type N on the field + FREE_MANEUVER = 0x27, // Enable movement over occupied tiles + HASTE = 0x28, // Multiply all move action costs by expr (which may be zero) + CLONE = 0x29, // Make setting this card free if at least one card of type N is already on the field + DEF_DISABLE_BY_COST = 0x2A, // Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive + FILIAL = 0x2B, // Increase controlling SC's HP by N when this card is destroyed + SNATCH = 0x2C, // Steal N EXP during attack + HAND_DISRUPTER = 0x2D, // Discard N cards from hand immediately + DROP = 0x2E, // Give Drop condition + ACTION_DISRUPTER = 0x2F, // Destroy all action cards used by attacker + SET_HP = 0x30, // Set HP to N + NATIVE_SHIELD = 0x31, // Block attacks from Native creatures + A_BEAST_SHIELD = 0x32, // Block attacks from A.Beast creatures + MACHINE_SHIELD = 0x33, // Block attacks from Machine creatures + DARK_SHIELD = 0x34, // Block attacks from Dark creatures + SWORD_SHIELD = 0x35, // Block attacks from Sword items + GUN_SHIELD = 0x36, // Block attacks from Gun items + CANE_SHIELD = 0x37, // Block attacks from Cane items + UNKNOWN_38 = 0x38, + UNKNOWN_39 = 0x39, + DEFENDER = 0x3A, // Make attacks go to setter of this card instead of original target + SURVIVAL_DECOYS = 0x3B, // Redirect damage for multi-sided attack + GIVE_OR_TAKE_EXP = 0x3C, // Give N EXP, or take if N is negative + UNKNOWN_3D = 0x3D, + DEATH_COMPANION = 0x3E, // If this card has 1 or 2 HP, set its HP to N + EXP_DECOY = 0x3F, // If defender has EXP, lose EXP instead of getting damage when attacked + SET_MV = 0x40, // Set MV to N + GROUP = 0x41, // Temporarily increase AP by N * number of this card on field, excluding itself + BERSERK = 0x42, // User of this card receives the same damage as target, and isn't helped by target's defense cards + GUARD_CREATURE = 0x43, // Attacks on controlling SC damage this card instead + TECH = 0x44, // Technique cards cost 1 fewer ATK point + BIG_SWING = 0x45, // Increase all attacking ATK costs by 1 + UNKNOWN_46 = 0x46, + SHIELD_WEAPON = 0x47, // Limit attacker's choice of target to guard items + ATK_DICE_BOOST = 0x48, // Increase ATK dice roll by 1 + UNKNOWN_49 = 0x49, + MAJOR_PIERCE = 0x4A, // If SC has over half of max HP, attacks target SC instead of equipped items + HEAVY_PIERCE = 0x4B, // If SC has 3 or more items equipped, attacks target SC instead of equipped items + MAJOR_RAMPAGE = 0x4C, // If SC has over half of max HP, attacks target SC and all equipped items + HEAVY_RAMPAGE = 0x4D, // If SC has 3 or more items equipped, attacks target SC and all equipped items + AP_GROWTH = 0x4E, // Permanently increase AP by N + TP_GROWTH = 0x4F, // Permanently increase TP by N + REBORN = 0x50, // If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded + COPY = 0x51, // Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent's values + UNKNOWN_52 = 0x52, + MISC_GUARDS = 0x53, // Add N to card's defense value + AP_OVERRIDE = 0x54, // Set AP to N temporarily + TP_OVERRIDE = 0x55, // Set TP to N temporarily + RETURN = 0x56, // Return card to hand on destruction instead of discarding + A_T_SWAP_PERM = 0x57, // Permanently swap AP and TP + A_H_SWAP_PERM = 0x58, // Permanently swap AP and HP + SLAYERS_ASSASSINS = 0x59, // Temporarily increase AP during attack + ANTI_ABNORMALITY_2 = 0x5A, // Remove all conditions + FIXED_RANGE = 0x5B, // Use SC's range instead of weapon or attack card ranges + ELUDE = 0x5C, // SC does not lose HP when equipped items are destroyed + PARRY = 0x5D, // Forward attack to a random FC within one tile of original target, excluding attacker and original target + BLOCK_ATTACK = 0x5E, // Completely block attack + UNKNOWN_5F = 0x5F, + UNKNOWN_60 = 0x60, + COMBO_TP = 0x61, // Gain TP equal to the number of cards of type N on the field + MISC_AP_BONUSES = 0x62, // Temporarily increase AP by N + MISC_TP_BONUSES = 0x63, // Temporarily increase TP by N + UNKNOWN_64 = 0x64, MISC_DEFENSE_BONUSES = 0x65, // Decrease damage by N - MOSTLY_HALFGUARDS = 0x66, // Reduce damage from incoming attack by N - PERIODIC_FIELD = 0x67, // Swap immunity to tech or physical attacks - FC_LIMIT_BY_COUNT = 0x68, // Change FC limit from 8 ATK points total to 4 FCs total - UNKNOWN_69 = 0x69, - MV_BONUS = 0x6A, // Increase MV by N - FORWARD_DAMAGE = 0x6B, - WEAK_SPOT_INFLUENCE = 0x6C, // Temporarily decrease AP by N - DAMAGE_MODIFIER_2 = 0x6D, // Set attack damage / AP after action cards applied (step 2) - WEAK_HIT_BLOCK = 0x6E, // Block all attacks of N damage or less - AP_SILENCE = 0x6F, // Temporarily decrease AP of opponent by N - TP_SILENCE = 0x70, // Temporarily decrease TP of opponent by N - A_T_SWAP = 0x71, // Temporarily swap AP and TP - HALFGUARD = 0x72, // Halve damage from attacks that would inflict N or more damage - UNKNOWN_73 = 0x73, - RAMPAGE_AP_LOSS = 0x74, // Temporarily reduce AP by N - UNKNOWN_75 = 0x75, - REFLECT = 0x76, // Generate reverse attack - UNKNOWN_77 = 0x77, - ANY = 0x78, // Not a real condition; used as a wildcard in search functions - UNKNOWN_79 = 0x79, - UNKNOWN_7A = 0x7A, - UNKNOWN_7B = 0x7B, - UNKNOWN_7C = 0x7C, - UNKNOWN_7D = 0x7D, - INVALID_FF = 0xFF, - ANY_FF = 0xFF, // Used as a wildcard in some search functions + MOSTLY_HALFGUARDS = 0x66, // Reduce damage from incoming attack by N + PERIODIC_FIELD = 0x67, // Swap immunity to tech or physical attacks + FC_LIMIT_BY_COUNT = 0x68, // Change FC limit from 8 ATK points total to 4 FCs total + UNKNOWN_69 = 0x69, + MV_BONUS = 0x6A, // Increase MV by N + FORWARD_DAMAGE = 0x6B, + WEAK_SPOT_INFLUENCE = 0x6C, // Temporarily decrease AP by N + DAMAGE_MODIFIER_2 = 0x6D, // Set attack damage / AP after action cards applied (step 2) + WEAK_HIT_BLOCK = 0x6E, // Block all attacks of N damage or less + AP_SILENCE = 0x6F, // Temporarily decrease AP of opponent by N + TP_SILENCE = 0x70, // Temporarily decrease TP of opponent by N + A_T_SWAP = 0x71, // Temporarily swap AP and TP + HALFGUARD = 0x72, // Halve damage from attacks that would inflict N or more damage + UNKNOWN_73 = 0x73, + RAMPAGE_AP_LOSS = 0x74, // Temporarily reduce AP by N + UNKNOWN_75 = 0x75, + REFLECT = 0x76, // Generate reverse attack + UNKNOWN_77 = 0x77, + ANY = 0x78, // Not a real condition; used as a wildcard in search functions + UNKNOWN_79 = 0x79, + UNKNOWN_7A = 0x7A, + UNKNOWN_7B = 0x7B, + UNKNOWN_7C = 0x7C, + UNKNOWN_7D = 0x7D, + INVALID_FF = 0xFF, + ANY_FF = 0xFF, // Used as a wildcard in some search functions }; const char* name_for_condition_type(ConditionType cond_type); enum class AssistEffect : uint16_t { - NONE = 0x0000, - DICE_HALF = 0x0001, - DICE_PLUS_1 = 0x0002, - DICE_FEVER = 0x0003, - CARD_RETURN = 0x0004, - LAND_PRICE = 0x0005, - POWERLESS_RAIN = 0x0006, - BRAVE_WIND = 0x0007, - SILENT_COLOSSEUM = 0x0008, - RESISTANCE = 0x0009, - INDEPENDENT = 0x000A, - ASSISTLESS = 0x000B, - ATK_DICE_2 = 0x000C, - DEFLATION = 0x000D, - INFLATION = 0x000E, - EXCHANGE = 0x000F, - INFLUENCE = 0x0010, - SKIP_SET = 0x0011, - SKIP_MOVE = 0x0012, - SKIP_ACT = 0x0013, - SKIP_DRAW = 0x0014, - FLY = 0x0015, - NECROMANCER = 0x0016, - PERMISSION = 0x0017, - SHUFFLE_ALL = 0x0018, - LEGACY = 0x0019, - ASSIST_REVERSE = 0x001A, - STAMINA = 0x001B, - AP_ABSORPTION = 0x001C, - HEAVY_FOG = 0x001D, - TRASH_1 = 0x001E, - EMPTY_HAND = 0x001F, - HITMAN = 0x0020, - ASSIST_TRASH = 0x0021, - SHUFFLE_GROUP = 0x0022, - ASSIST_VANISH = 0x0023, - CHARITY = 0x0024, - INHERITANCE = 0x0025, - FIX = 0x0026, - MUSCULAR = 0x0027, - CHANGE_BODY = 0x0028, - GOD_WHIM = 0x0029, - GOLD_RUSH = 0x002A, - ASSIST_RETURN = 0x002B, - REQUIEM = 0x002C, - RANSOM = 0x002D, - SIMPLE = 0x002E, - SLOW_TIME = 0x002F, - QUICK_TIME = 0x0030, - TERRITORY = 0x0031, - OLD_TYPE = 0x0032, - FLATLAND = 0x0033, - IMMORTALITY = 0x0034, - SNAIL_PACE = 0x0035, - TECH_FIELD = 0x0036, - FOREST_RAIN = 0x0037, - CAVE_WIND = 0x0038, - MINE_BRIGHTNESS = 0x0039, - RUIN_DARKNESS = 0x003A, - SABER_DANCE = 0x003B, - BULLET_STORM = 0x003C, - CANE_PALACE = 0x003D, - GIANT_GARDEN = 0x003E, + NONE = 0x0000, + DICE_HALF = 0x0001, + DICE_PLUS_1 = 0x0002, + DICE_FEVER = 0x0003, + CARD_RETURN = 0x0004, + LAND_PRICE = 0x0005, + POWERLESS_RAIN = 0x0006, + BRAVE_WIND = 0x0007, + SILENT_COLOSSEUM = 0x0008, + RESISTANCE = 0x0009, + INDEPENDENT = 0x000A, + ASSISTLESS = 0x000B, + ATK_DICE_2 = 0x000C, + DEFLATION = 0x000D, + INFLATION = 0x000E, + EXCHANGE = 0x000F, + INFLUENCE = 0x0010, + SKIP_SET = 0x0011, + SKIP_MOVE = 0x0012, + SKIP_ACT = 0x0013, + SKIP_DRAW = 0x0014, + FLY = 0x0015, + NECROMANCER = 0x0016, + PERMISSION = 0x0017, + SHUFFLE_ALL = 0x0018, + LEGACY = 0x0019, + ASSIST_REVERSE = 0x001A, + STAMINA = 0x001B, + AP_ABSORPTION = 0x001C, + HEAVY_FOG = 0x001D, + TRASH_1 = 0x001E, + EMPTY_HAND = 0x001F, + HITMAN = 0x0020, + ASSIST_TRASH = 0x0021, + SHUFFLE_GROUP = 0x0022, + ASSIST_VANISH = 0x0023, + CHARITY = 0x0024, + INHERITANCE = 0x0025, + FIX = 0x0026, + MUSCULAR = 0x0027, + CHANGE_BODY = 0x0028, + GOD_WHIM = 0x0029, + GOLD_RUSH = 0x002A, + ASSIST_RETURN = 0x002B, + REQUIEM = 0x002C, + RANSOM = 0x002D, + SIMPLE = 0x002E, + SLOW_TIME = 0x002F, + QUICK_TIME = 0x0030, + TERRITORY = 0x0031, + OLD_TYPE = 0x0032, + FLATLAND = 0x0033, + IMMORTALITY = 0x0034, + SNAIL_PACE = 0x0035, + TECH_FIELD = 0x0036, + FOREST_RAIN = 0x0037, + CAVE_WIND = 0x0038, + MINE_BRIGHTNESS = 0x0039, + RUIN_DARKNESS = 0x003A, + SABER_DANCE = 0x003B, + BULLET_STORM = 0x003C, + CANE_PALACE = 0x003D, + GIANT_GARDEN = 0x003E, MARCH_OF_THE_MEEK = 0x003F, - SUPPORT = 0x0040, - RICH = 0x0041, - REVERSE_CARD = 0x0042, - VENGEANCE = 0x0043, - SQUEEZE = 0x0044, - HOMESICK = 0x0045, - BOMB = 0x0046, - SKIP_TURN = 0x0047, - BATTLE_ROYALE = 0x0048, - DICE_FEVER_PLUS = 0x0049, - RICH_PLUS = 0x004A, - CHARITY_PLUS = 0x004B, - ANY = 0x004C, // Unused on cards; used in some search functions + SUPPORT = 0x0040, + RICH = 0x0041, + REVERSE_CARD = 0x0042, + VENGEANCE = 0x0043, + SQUEEZE = 0x0044, + HOMESICK = 0x0045, + BOMB = 0x0046, + SKIP_TURN = 0x0047, + BATTLE_ROYALE = 0x0048, + DICE_FEVER_PLUS = 0x0049, + RICH_PLUS = 0x004A, + CHARITY_PLUS = 0x004B, + ANY = 0x004C, // Unused on cards; used in some search functions }; enum class BattlePhase : uint8_t { @@ -413,8 +407,6 @@ enum class RegistrationPhase : uint8_t { INVALID_FF = 0xFF, }; - - enum class Direction : uint8_t { RIGHT = 0, UP = 1, @@ -711,8 +703,6 @@ struct StateFlags { void clear_FF(); } __attribute__((packed)); - - struct MapList { be_uint32_t num_maps; be_uint32_t unknown_a1; // Always 0? @@ -875,10 +865,10 @@ struct MapDefinition { // .mnmd format; also the format of (decompressed) quests /* 59B0 */ parray reward_card_ids; - /* 59D0 */be_uint32_t unknown_a9_a; - /* 59D4 */be_uint32_t unknown_a9_b; - /* 59D8 */be_uint16_t unknown_a9_c; - /* 59DA */be_uint16_t unknown_a9_d; + /* 59D0 */ be_uint32_t unknown_a9_a; + /* 59D4 */ be_uint32_t unknown_a9_b; + /* 59D8 */ be_uint16_t unknown_a9_c; + /* 59DA */ be_uint16_t unknown_a9_d; /* 59DC */ uint8_t unknown_a10; @@ -931,8 +921,6 @@ struct MapDefinition { // .mnmd format; also the format of (decompressed) quests std::string str(const DataIndex* data_index = nullptr) const; } __attribute__((packed)); - - struct COMDeckDefinition { size_t index; std::string player_name; @@ -940,8 +928,6 @@ struct COMDeckDefinition { parray card_ids; }; - - class DataIndex { public: DataIndex(const std::string& directory, uint32_t behavior_flags); @@ -1004,6 +990,4 @@ private: std::unordered_map> com_decks_by_name; }; - - } // namespace Episode3 diff --git a/src/Episode3/DeckState.cc b/src/Episode3/DeckState.cc index 8ae0ab71..679b5754 100644 --- a/src/Episode3/DeckState.cc +++ b/src/Episode3/DeckState.cc @@ -4,8 +4,6 @@ using namespace std; namespace Episode3 { - - NameEntry::NameEntry() { this->clear(); } @@ -17,8 +15,6 @@ void NameEntry::clear() { this->unused = 0; } - - DeckEntry::DeckEntry() { this->clear(); } @@ -32,8 +28,6 @@ void DeckEntry::clear() { this->card_ids.clear(0xFFFF); } - - uint8_t index_for_card_ref(uint16_t card_ref) { return card_ref & 0xFF; } @@ -42,8 +36,6 @@ uint8_t client_id_for_card_ref(uint16_t card_ref) { return (card_ref >> 8) & 0xFF; } - - uint8_t DeckState::num_drawable_cards() const { return this->card_refs.size() - this->draw_index; } @@ -102,8 +94,8 @@ bool DeckState::draw_card_by_ref(uint16_t card_ref) { this->entries[index].state = CardState::IN_HAND; return true; - // If the card is still drawable, we need to move it so it's just in front of - // the draw index, then immediately draw it + // If the card is still drawable, we need to move it so it's just in front of + // the draw index, then immediately draw it } else if (this->entries[index].state == CardState::DRAWABLE) { ssize_t ref_index; for (ref_index = this->card_refs.size(); ref_index >= 0; ref_index--) { @@ -281,6 +273,4 @@ void DeckState::shuffle() { } } - - } // namespace Episode3 diff --git a/src/Episode3/DeckState.hh b/src/Episode3/DeckState.hh index 1bffa389..7be36fa8 100644 --- a/src/Episode3/DeckState.hh +++ b/src/Episode3/DeckState.hh @@ -4,13 +4,11 @@ #include -#include "../Text.hh" #include "../PSOEncryption.hh" +#include "../Text.hh" namespace Episode3 { - - struct NameEntry { parray name; uint8_t client_id; @@ -57,12 +55,12 @@ public: uint8_t client_id, const parray& card_ids, std::shared_ptr random_crypt) - : client_id(client_id), - draw_index(1), - card_ref_base(this->client_id << 8), - shuffle_enabled(true), - loop_enabled(true), - random_crypt(random_crypt) { + : client_id(client_id), + draw_index(1), + card_ref_base(this->client_id << 8), + shuffle_enabled(true), + loop_enabled(true), + random_crypt(random_crypt) { for (size_t z = 0; z < card_ids.size(); z++) { auto& e = this->entries[z]; e.card_id = card_ids[z]; @@ -112,6 +110,4 @@ private: std::shared_ptr random_crypt; }; - - } // namespace Episode3 diff --git a/src/Episode3/MapState.cc b/src/Episode3/MapState.cc index 08766327..ce37b38b 100644 --- a/src/Episode3/MapState.cc +++ b/src/Episode3/MapState.cc @@ -4,8 +4,6 @@ using namespace std; namespace Episode3 { - - MapState::MapState() { this->clear(); } @@ -32,8 +30,6 @@ void MapState::print(FILE* stream) const { } } - - MapAndRulesState::MapAndRulesState() { this->clear(); } @@ -54,8 +50,6 @@ void MapAndRulesState::clear() { this->unused5 = 0; } - - bool MapAndRulesState::loc_is_within_bounds(uint8_t x, uint8_t y) const { return (x < this->map.width) && (y < this->map.height); } @@ -75,8 +69,6 @@ void MapAndRulesState::clear_occupied_bit_for_tile(uint8_t x, uint8_t y) { this->map.tiles[y][x] &= 0xEF; } - - OverlayState::OverlayState() { this->clear(); } @@ -90,6 +82,4 @@ void OverlayState::clear() { this->unused3.clear(0); } - - } // namespace Episode3 diff --git a/src/Episode3/MapState.hh b/src/Episode3/MapState.hh index 7baac7f8..d136e7ea 100644 --- a/src/Episode3/MapState.hh +++ b/src/Episode3/MapState.hh @@ -9,8 +9,6 @@ namespace Episode3 { - - struct MapState { le_uint16_t width; le_uint16_t height; @@ -58,6 +56,4 @@ struct OverlayState { void clear(); } __attribute__((packed)); - - } // namespace Episode3 diff --git a/src/Episode3/PlayerState.cc b/src/Episode3/PlayerState.cc index 35da12bd..71ad9f6b 100644 --- a/src/Episode3/PlayerState.cc +++ b/src/Episode3/PlayerState.cc @@ -6,40 +6,38 @@ using namespace std; namespace Episode3 { - - PlayerState::PlayerState(uint8_t client_id, shared_ptr server) - : w_server(server), - client_id(client_id), - num_mulligans_allowed(1), - sc_card_type(CardType::HUNTERS_SC), - team_id(0xFF), - atk_points(0), - def_points(0), - atk_points2(0), - atk_points2_max(6), - atk_bonuses(0), - def_bonuses(0), - dice_results(0), - unknown_a4(2), - dice_max(6), - total_set_cards_cost(0), - sc_card_id(0xFFFF), - sc_card_ref(0xFFFF), - card_refs(0xFFFF), - discard_log_card_refs(0xFFFF), - discard_log_reasons(0), - assist_remaining_turns(0), - assist_card_set_number(0), - set_assist_card_id(0xFFFF), - god_whim_can_use_hidden_cards(false), - unknown_a14(0), - assist_flags(0), - assist_delay_turns(0), - start_facing_direction(Direction::RIGHT), - num_destroyed_fcs(0), - unknown_a16(0), - unknown_a17(0) { } + : w_server(server), + client_id(client_id), + num_mulligans_allowed(1), + sc_card_type(CardType::HUNTERS_SC), + team_id(0xFF), + atk_points(0), + def_points(0), + atk_points2(0), + atk_points2_max(6), + atk_bonuses(0), + def_bonuses(0), + dice_results(0), + unknown_a4(2), + dice_max(6), + total_set_cards_cost(0), + sc_card_id(0xFFFF), + sc_card_ref(0xFFFF), + card_refs(0xFFFF), + discard_log_card_refs(0xFFFF), + discard_log_reasons(0), + assist_remaining_turns(0), + assist_card_set_number(0), + set_assist_card_id(0xFFFF), + god_whim_can_use_hidden_cards(false), + unknown_a14(0), + assist_flags(0), + assist_delay_turns(0), + start_facing_direction(Direction::RIGHT), + num_destroyed_fcs(0), + unknown_a16(0), + unknown_a17(0) {} void PlayerState::init() { if (this->server()->player_states[this->client_id].get() != this) { @@ -1411,7 +1409,8 @@ void PlayerState::update_hand_and_equip_state_and_send_6xB4x02_if_needed( cmd.state.sc_card_ref = this->sc_card_ref; cmd.state.assist_card_ref2 = this->card_refs[6]; cmd.state.assist_card_set_number = (this->card_refs[6] == 0xFFFF) - ? 0 : this->assist_card_set_number; + ? 0 + : this->assist_card_set_number; cmd.state.assist_card_id = this->set_assist_card_id; cmd.state.assist_remaining_turns = this->assist_remaining_turns; cmd.state.assist_delay_turns = this->assist_delay_turns; @@ -1830,6 +1829,4 @@ void PlayerState::compute_team_dice_boost_after_draw_phase() { this->update_hand_and_equip_state_and_send_6xB4x02_if_needed(); } - - } // namespace Episode3 diff --git a/src/Episode3/PlayerState.hh b/src/Episode3/PlayerState.hh index e92c6b7e..bb37fac5 100644 --- a/src/Episode3/PlayerState.hh +++ b/src/Episode3/PlayerState.hh @@ -5,15 +5,13 @@ #include #include "../Text.hh" -#include "DataIndex.hh" #include "Card.hh" +#include "DataIndex.hh" #include "DeckState.hh" #include "PlayerStateSubordinates.hh" namespace Episode3 { - - class ServerBase; class Server; @@ -25,8 +23,7 @@ public: std::shared_ptr server() const; bool draw_cards_allowed() const; - void apply_assist_card_effect_on_set( - std::shared_ptr setter_ps); + void apply_assist_card_effect_on_set(std::shared_ptr setter_ps); void apply_dice_effects(); uint16_t card_ref_for_hand_index(size_t hand_index) const; int16_t compute_attack_or_defense_atk_costs(const ActionState& pa) const; @@ -188,6 +185,4 @@ public: PlayerStats stats; }; - - } // namespace Episode3 diff --git a/src/Episode3/PlayerStateSubordinates.cc b/src/Episode3/PlayerStateSubordinates.cc index 147ca50a..887db429 100644 --- a/src/Episode3/PlayerStateSubordinates.cc +++ b/src/Episode3/PlayerStateSubordinates.cc @@ -6,8 +6,6 @@ using namespace std; namespace Episode3 { - - template std::string string_for_refs(const parray& card_refs) { string ret = "["; @@ -24,26 +22,24 @@ std::string string_for_refs(const parray& card_refs) { return ret; } - - Condition::Condition() { this->clear(); } bool Condition::operator==(const Condition& other) const { return (this->type == other.type) && - (this->remaining_turns == other.remaining_turns) && - (this->a_arg_value == other.a_arg_value) && - (this->dice_roll_value == other.dice_roll_value) && - (this->flags == other.flags) && - (this->card_definition_effect_index == other.card_definition_effect_index) && - (this->card_ref == other.card_ref) && - (this->value == other.value) && - (this->condition_giver_card_ref == other.condition_giver_card_ref) && - (this->random_percent == other.random_percent) && - (this->value8 == other.value8) && - (this->order == other.order) && - (this->unknown_a8 == other.unknown_a8); + (this->remaining_turns == other.remaining_turns) && + (this->a_arg_value == other.a_arg_value) && + (this->dice_roll_value == other.dice_roll_value) && + (this->flags == other.flags) && + (this->card_definition_effect_index == other.card_definition_effect_index) && + (this->card_ref == other.card_ref) && + (this->value == other.value) && + (this->condition_giver_card_ref == other.condition_giver_card_ref) && + (this->random_percent == other.random_percent) && + (this->value8 == other.value8) && + (this->order == other.order) && + (this->unknown_a8 == other.unknown_a8); } bool Condition::operator!=(const Condition& other) const { return !this->operator==(other); @@ -84,8 +80,8 @@ void Condition::clear_FF() { std::string Condition::str() const { return string_printf( "Condition[type=%s, turns=%hhu, a_arg=%hhd, dice=%hhu, flags=%02hhX, " - "def_eff_index=%hhu, ref=@%04hX, value=%hd, giver_ref=@%04hX " - "percent=%hhu value8=%hd order=%hu a8=%hu]", + "def_eff_index=%hhu, ref=@%04hX, value=%hd, giver_ref=@%04hX " + "percent=%hhu value8=%hd order=%hu a8=%hu]", name_for_condition_type(this->type), this->remaining_turns, this->a_arg_value, @@ -101,8 +97,6 @@ std::string Condition::str() const { this->unknown_a8); } - - EffectResult::EffectResult() { this->clear(); } @@ -123,8 +117,8 @@ void EffectResult::clear() { std::string EffectResult::str() const { return string_printf( "EffectResult[att_ref=@%04hX, target_ref=@%04hX, value=%hhd, " - "cur_hp=%hhd, ap=%hhd, tp=%hhd, flags=%02hhX, op=%hhd, " - "cond_index=%hhu, dice=%hhu]", + "cur_hp=%hhd, ap=%hhd, tp=%hhd, flags=%02hhX, op=%hhd, " + "cond_index=%hhu, dice=%hhu]", this->attacker_card_ref.load(), this->target_card_ref.load(), this->value, @@ -137,20 +131,18 @@ std::string EffectResult::str() const { this->dice_roll_value); } - - CardShortStatus::CardShortStatus() { this->clear(); } bool CardShortStatus::operator==(const CardShortStatus& other) const { return (this->card_ref == other.card_ref) && - (this->current_hp == other.current_hp) && - (this->card_flags == other.card_flags) && - (this->loc == other.loc) && - (this->unused1 == other.unused1) && - (this->max_hp == other.max_hp) && - (this->unused2 == other.unused2); + (this->current_hp == other.current_hp) && + (this->card_flags == other.card_flags) && + (this->loc == other.loc) && + (this->unused1 == other.unused1) && + (this->max_hp == other.max_hp) && + (this->unused2 == other.unused2); } bool CardShortStatus::operator!=(const CardShortStatus& other) const { return !this->operator==(other); @@ -160,7 +152,7 @@ std::string CardShortStatus::str() const { string loc_s = this->loc.str(); return string_printf( "CardShortStatus[ref=@%04hX, cur_hp=%hd, flags=%08" PRIX32 ", loc=%s, " - "u1=%04hX, max_hp=%hhd, u2=%hhu]", + "u1=%04hX, max_hp=%hhd, u2=%hhu]", this->card_ref.load(), this->current_hp.load(), this->card_flags.load(), @@ -190,8 +182,6 @@ void CardShortStatus::clear_FF() { this->unused2 = 0xFF; } - - ActionState::ActionState() { this->clear(); } @@ -212,8 +202,8 @@ std::string ActionState::str() const { string action_refs_s = string_for_refs(this->action_card_refs); return string_printf( "ActionState[client=%hu, u=%hhu, facing=%s, attacker_ref=@%04hX, " - "def_ref=@%04hX, target_refs=%s, action_refs=%s, " - "orig_attacker_ref=@%04hX]", + "def_ref=@%04hX, target_refs=%s, action_refs=%s, " + "orig_attacker_ref=@%04hX]", this->client_id.load(), this->unused, name_for_direction(this->facing_direction), @@ -224,34 +214,32 @@ std::string ActionState::str() const { this->original_attacker_card_ref.load()); } - - ActionChain::ActionChain() { this->clear(); } bool ActionChain::operator==(const ActionChain& other) const { return (this->effective_ap == other.effective_ap) && - (this->effective_tp == other.effective_tp) && - (this->ap_effect_bonus == other.ap_effect_bonus) && - (this->damage == other.damage) && - (this->acting_card_ref == other.acting_card_ref) && - (this->unknown_card_ref_a3 == other.unknown_card_ref_a3) && - (this->attack_action_card_refs == other.attack_action_card_refs) && - (this->attack_action_card_ref_count == other.attack_action_card_ref_count) && - (this->attack_medium == other.attack_medium) && - (this->target_card_ref_count == other.target_card_ref_count) && - (this->action_subphase == other.action_subphase) && - (this->strike_count == other.strike_count) && - (this->damage_multiplier == other.damage_multiplier) && - (this->attack_number == other.attack_number) && - (this->tp_effect_bonus == other.tp_effect_bonus) && - (this->unused1 == other.unused1) && - (this->unused2 == other.unused2) && - (this->card_ap == other.card_ap) && - (this->card_tp == other.card_tp) && - (this->flags == other.flags) && - (this->target_card_refs == other.target_card_refs); + (this->effective_tp == other.effective_tp) && + (this->ap_effect_bonus == other.ap_effect_bonus) && + (this->damage == other.damage) && + (this->acting_card_ref == other.acting_card_ref) && + (this->unknown_card_ref_a3 == other.unknown_card_ref_a3) && + (this->attack_action_card_refs == other.attack_action_card_refs) && + (this->attack_action_card_ref_count == other.attack_action_card_ref_count) && + (this->attack_medium == other.attack_medium) && + (this->target_card_ref_count == other.target_card_ref_count) && + (this->action_subphase == other.action_subphase) && + (this->strike_count == other.strike_count) && + (this->damage_multiplier == other.damage_multiplier) && + (this->attack_number == other.attack_number) && + (this->tp_effect_bonus == other.tp_effect_bonus) && + (this->unused1 == other.unused1) && + (this->unused2 == other.unused2) && + (this->card_ap == other.card_ap) && + (this->card_tp == other.card_tp) && + (this->flags == other.flags) && + (this->target_card_refs == other.target_card_refs); } bool ActionChain::operator!=(const ActionChain& other) const { return !this->operator==(other); @@ -262,12 +250,12 @@ std::string ActionChain::str() const { string target_card_refs_s = string_for_refs(this->target_card_refs); return string_printf( "ActionChain[eff_ap=%hhd, eff_tp=%hhd, ap_bonus=%hhd, damage=%hhd, " - "acting_ref=@%04hX, unknown_ref_a3=@%04hX, " - "attack_action_refs=%s, attack_action_ref_count=%hhu, " - "medium=%s, target_ref_count=%hhu, subphase=%s, " - "strikes=%hhu, damage_mult=%hhd, attack_num=%hhu, " - "tp_bonus=%hhd, u1=%hhu, u2=%hhu, card_ap=%hhd, " - "card_tp=%hhd, flags=%08" PRIX32 ", target_refs=%s]", + "acting_ref=@%04hX, unknown_ref_a3=@%04hX, " + "attack_action_refs=%s, attack_action_ref_count=%hhu, " + "medium=%s, target_ref_count=%hhu, subphase=%s, " + "strikes=%hhu, damage_mult=%hhd, attack_num=%hhu, " + "tp_bonus=%hhd, u1=%hhu, u2=%hhu, card_ap=%hhd, " + "card_tp=%hhd, flags=%08" PRIX32 ", target_refs=%s]", this->effective_ap, this->effective_tp, this->ap_effect_bonus, @@ -339,8 +327,6 @@ void ActionChain::clear_FF() { this->target_card_refs.clear(0xFFFF); } - - ActionChainWithConds::ActionChainWithConds() { this->clear(); } @@ -495,24 +481,22 @@ bool ActionChainWithConds::unknown_8024DEC4() const { return this->check_flag(4) ? false : (this->chain.target_card_ref_count != 0); } - - ActionMetadata::ActionMetadata() { this->clear(); } bool ActionMetadata::operator==(const ActionMetadata& other) const { return (this->card_ref == other.card_ref) && - (this->target_card_ref_count == other.target_card_ref_count) && - (this->defense_card_ref_count == other.defense_card_ref_count) && - (this->action_subphase == other.action_subphase) && - (this->defense_power == other.defense_power) && - (this->defense_bonus == other.defense_bonus) && - (this->attack_bonus == other.attack_bonus) && - (this->flags == other.flags) && - (this->target_card_refs == other.target_card_refs) && - (this->defense_card_refs == other.defense_card_refs) && - (this->original_attacker_card_refs == other.original_attacker_card_refs); + (this->target_card_ref_count == other.target_card_ref_count) && + (this->defense_card_ref_count == other.defense_card_ref_count) && + (this->action_subphase == other.action_subphase) && + (this->defense_power == other.defense_power) && + (this->defense_bonus == other.defense_bonus) && + (this->attack_bonus == other.attack_bonus) && + (this->flags == other.flags) && + (this->target_card_refs == other.target_card_refs) && + (this->defense_card_refs == other.defense_card_refs) && + (this->original_attacker_card_refs == other.original_attacker_card_refs); } bool ActionMetadata::operator!=(const ActionMetadata& other) const { return !this->operator==(other); @@ -524,9 +508,9 @@ std::string ActionMetadata::str() const { string original_attacker_card_refs_s = string_for_refs(this->original_attacker_card_refs); return string_printf( "ActionMetadata[ref=@%04hX, target_ref_count=%hhu, def_ref_count=%hhu, " - "subphase=%s, def_power=%hhd, def_bonus=%hhd, " - "att_bonus=%hhd, flags=%08" PRIX32 ", target_refs=%s, " - "defense_refs=%s, original_attacker_refs=%s]", + "subphase=%s, def_power=%hhd, def_bonus=%hhd, " + "att_bonus=%hhd, flags=%08" PRIX32 ", target_refs=%s, " + "defense_refs=%s, original_attacker_refs=%s]", this->card_ref.load(), this->target_card_ref_count, this->defense_card_ref_count, @@ -610,8 +594,6 @@ void ActionMetadata::add_defense_card_ref( } } - - HandAndEquipState::HandAndEquipState() { this->clear(); } @@ -623,13 +605,13 @@ std::string HandAndEquipState::str() const { string set_card_refs2_s = string_for_refs(this->set_card_refs2); return string_printf( "HandAndEquipState[dice=[%hhu, %hhu], atk=%hhu, def=%hhu, atk2=%hhu, " - "a1=%hhu, total_set_cost=%hhu, is_cpu=%hhu, " - "assist_flags=%08" PRIX32 ", hand_refs=%s, " - "assist_ref=@%04hX, set_refs=%s, sc_ref=@%04hX, " - "hand_refs2=%s, set_refs2=%s, assist_ref2=@%04hX, " - "assist_set_num=%hu, assist_card_id=%04hX, " - "assist_turns=%hhu, assit_dely=%hhu, atk_bonus=%hhu, " - "def_bonus=%hhu, u2=[%hhu, %hhu]]", + "a1=%hhu, total_set_cost=%hhu, is_cpu=%hhu, " + "assist_flags=%08" PRIX32 ", hand_refs=%s, " + "assist_ref=@%04hX, set_refs=%s, sc_ref=@%04hX, " + "hand_refs2=%s, set_refs2=%s, assist_ref2=@%04hX, " + "assist_set_num=%hu, assist_card_id=%04hX, " + "assist_turns=%hhu, assit_dely=%hhu, atk_bonus=%hhu, " + "def_bonus=%hhu, u2=[%hhu, %hhu]]", this->dice_results[0], this->dice_results[1], this->atk_points, @@ -706,8 +688,6 @@ void HandAndEquipState::clear_FF() { this->unused2.clear(0xFF); } - - PlayerStats::PlayerStats() { this->clear(); } @@ -747,12 +727,7 @@ float PlayerStats::score(size_t num_rounds) const { // Ep3 PsoV3.dol, so it's presumably correct. Is the PSO-World formula simply // incorrect, or is it from e.g. the Japanese version, which may have a // different rank calculation function? - return 38.0f - + 0.8f * this->action_card_negated_damage - - 2.3f * num_rounds - - 1.8f * this->sc_damage_taken - + 3.0f * this->max_attack_combo_size - + (this->damage_given - this->damage_taken); + return 38.0f + 0.8f * this->action_card_negated_damage - 2.3f * num_rounds - 1.8f * this->sc_damage_taken + 3.0f * this->max_attack_combo_size + (this->damage_given - this->damage_taken); } uint8_t PlayerStats::rank(size_t num_rounds) const { @@ -767,7 +742,7 @@ constexpr size_t RANK_THRESHOLD_COUNT = 9; static const float RANK_THRESHOLDS[RANK_THRESHOLD_COUNT] = { 15.0f, 25.0f, 30.0f, 40.0f, 50.0f, 60.0f, 65.0f, 75.0f, 85.0f}; static const char* RANK_NAMES[RANK_THRESHOLD_COUNT + 1] = { - "E", "D", "D+", "C", "C+", "B", "B+", "A", "A+", "S"}; + "E", "D", "D+", "C", "C+", "B", "B+", "A", "A+", "S"}; uint8_t PlayerStats::rank_for_score(float score) { size_t rank = 0; @@ -784,9 +759,6 @@ const char* PlayerStats::name_for_rank(uint8_t rank) { return RANK_NAMES[rank]; } - - - bool is_card_within_range( const parray& range, const Location& anchor_loc, @@ -824,6 +796,4 @@ vector get_card_refs_within_range( return ret; } - - } // namespace Episode3 diff --git a/src/Episode3/PlayerStateSubordinates.hh b/src/Episode3/PlayerStateSubordinates.hh index 21caad85..f5403743 100644 --- a/src/Episode3/PlayerStateSubordinates.hh +++ b/src/Episode3/PlayerStateSubordinates.hh @@ -9,8 +9,6 @@ namespace Episode3 { - - class ServerBase; class Server; class Card; @@ -269,13 +267,9 @@ struct PlayerStats { static const char* name_for_rank(uint8_t rank); } __attribute__((packed)); - - std::vector get_card_refs_within_range( const parray& range, const Location& loc, const parray& short_statuses); - - } // namespace Episode3 diff --git a/src/Episode3/RulerServer.cc b/src/Episode3/RulerServer.cc index 24d2f004..f4c8c2a8 100644 --- a/src/Episode3/RulerServer.cc +++ b/src/Episode3/RulerServer.cc @@ -6,8 +6,6 @@ using namespace std; namespace Episode3 { - - void compute_effective_range( parray& ret, shared_ptr data_index, @@ -189,14 +187,12 @@ bool card_linkage_is_valid( return false; } - - RulerServer::RulerServer(shared_ptr server) - : w_server(server), - team_id_for_client_id(0xFF), - error_code1(0), - error_code2(0), - error_code3(0) { } + : w_server(server), + team_id_for_client_id(0xFF), + error_code1(0), + error_code2(0), + error_code3(0) {} shared_ptr RulerServer::server() { auto s = this->w_server.lock(); @@ -318,11 +314,11 @@ bool RulerServer::attack_action_has_rampage_and_not_pierce( auto attack_medium = this->get_attack_medium(pa); if (!this->compute_effective_range_and_target_mode_for_attack( - pa, &effective_range_card_id, &effective_target_mode, &orig_card_ref)) { + pa, &effective_range_card_id, &effective_target_mode, &orig_card_ref)) { return false; } - if ((orig_card_ref != 0xFFFF) && (orig_card_ref != pa.attacker_card_ref) && + if ((orig_card_ref != 0xFFFF) && (orig_card_ref != pa.attacker_card_ref) && !this->check_usability_or_apply_condition_for_card_refs( orig_card_ref, pa.attacker_card_ref, card_ref, 0xFF, AttackMedium::INVALID_FF)) { return false; @@ -426,9 +422,9 @@ bool RulerServer::attack_action_has_pierce_and_not_rampage( for (; last_cond_index >= 0; last_cond_index--) { bool has_rampage = false; if (this->card_has_pierce_or_rampage( - client_id, ce->def.effects[last_cond_index].type, &has_rampage, - pa.attacker_card_ref, pa.action_card_refs[last_action_card_index], - last_cond_index, attack_medium)) { + client_id, ce->def.effects[last_cond_index].type, &has_rampage, + pa.attacker_card_ref, pa.action_card_refs[last_action_card_index], + last_cond_index, attack_medium)) { return true; } if (has_rampage) { @@ -442,10 +438,10 @@ bool RulerServer::attack_action_has_pierce_and_not_rampage( for (ssize_t cond_index = 8; cond_index >= 0; cond_index--) { bool has_rampage = false; if (this->card_has_pierce_or_rampage( - client_id, chain->conditions[cond_index].type, &has_rampage, - pa.attacker_card_ref, chain->conditions[cond_index].card_ref, - chain->conditions[cond_index].card_definition_effect_index, - attack_medium)) { + client_id, chain->conditions[cond_index].type, &has_rampage, + pa.attacker_card_ref, chain->conditions[cond_index].card_ref, + chain->conditions[cond_index].card_definition_effect_index, + attack_medium)) { return true; } if (has_rampage) { @@ -457,7 +453,6 @@ bool RulerServer::attack_action_has_pierce_and_not_rampage( return false; } - bool RulerServer::card_exists_by_status(const CardShortStatus& stat) const { if ((stat.card_flags & 3) || (stat.card_ref == 0xFFFF)) { return false; @@ -494,10 +489,10 @@ bool RulerServer::card_id_is_boss_sc(uint16_t card_id) { bool RulerServer::card_id_is_support_tech_or_support_pb(uint16_t card_id) { return (card_id == 0x00E1) || - (card_id == 0x00E2) || - (card_id == 0x00E6) || - (card_id == 0x00EB) || - (card_id == 0x00EC); + (card_id == 0x00E2) || + (card_id == 0x00E6) || + (card_id == 0x00EB) || + (card_id == 0x00EC); } bool RulerServer::card_ref_can_attack(uint16_t card_ref) { @@ -537,11 +532,11 @@ bool RulerServer::card_ref_can_attack(uint16_t card_ref) { // then the item also cannot attack if ((ce->def.type == CardType::ITEM) && (!this->short_statuses[client_id] || - (this->short_statuses[client_id]->at(0).card_ref == 0xFFFF) || - this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::HOLD) || - this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::GUOM) || - this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::PARALYZE) || - this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::FREEZE))) { + (this->short_statuses[client_id]->at(0).card_ref == 0xFFFF) || + this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::HOLD) || + this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::GUOM) || + this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::PARALYZE) || + this->find_condition_on_card_ref(this->short_statuses[client_id]->at(0).card_ref, ConditionType::FREEZE))) { return false; } @@ -589,7 +584,7 @@ bool RulerServer::card_ref_can_move( const auto& item_stat = short_statuses->at(z); if ((item_stat.card_ref != 0xFFFF) && this->card_exists_by_status(item_stat) && (this->find_condition_on_card_ref(item_stat.card_ref, ConditionType::GUOM) || - this->find_condition_on_card_ref(item_stat.card_ref, ConditionType::IMMOBILE))) { + this->find_condition_on_card_ref(item_stat.card_ref, ConditionType::IMMOBILE))) { return false; } } @@ -951,11 +946,11 @@ bool RulerServer::check_usability_or_condition_apply( // positioning/team setup if (is_item_usability_check && ((criterion_code == CriterionCode::SAME_TEAM) || - (criterion_code == CriterionCode::SAME_PLAYER) || - (criterion_code == CriterionCode::SAME_TEAM_NOT_SAME_PLAYER) || - (criterion_code == CriterionCode::UNKNOWN_07) || - (criterion_code == CriterionCode::NOT_SC) || - (criterion_code == CriterionCode::SC))) { + (criterion_code == CriterionCode::SAME_PLAYER) || + (criterion_code == CriterionCode::SAME_TEAM_NOT_SAME_PLAYER) || + (criterion_code == CriterionCode::UNKNOWN_07) || + (criterion_code == CriterionCode::NOT_SC) || + (criterion_code == CriterionCode::SC))) { criterion_code = CriterionCode::NONE; } @@ -988,7 +983,7 @@ bool RulerServer::check_usability_or_condition_apply( case CriterionCode::SAME_TEAM: if ((client_id1 == client_id2) || ((client_id1 != 0xFF) && (client_id2 != 0xFF) && - (this->team_id_for_client_id[client_id1] == this->team_id_for_client_id[client_id2]))) { + (this->team_id_for_client_id[client_id1] == this->team_id_for_client_id[client_id2]))) { return true; } break; @@ -1026,255 +1021,255 @@ bool RulerServer::check_usability_or_condition_apply( break; case CriterionCode::HUNTER_HUMAN_SC: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0002, // Kranz - 0x0003, // Ino'lis - 0x0004, // Sil'fer - 0x0006, // Kylria - 0x0111, // Relmitos - 0x0112, // Viviana - 0x0115, // Glustar - 0x02AA, // H-HUmar - 0x02AB, // H-HUnewearl - 0x02AE, // H-RAmar - 0x02AF, // H-RAmarl - 0x02B2, // H-FOmar - 0x02B3, // H-FOmarl - 0x02B4, // H-FOnewm - 0x02B5, // H-FOnewearl - 0x02CC, // H-HUmar - 0x02CD, // H-RAmarl - 0x02CE, // H-FOmarl - 0x02CF, // H-HUnewearl - 0x02D1, // H-RAmarl - 0x02D5, // H-FOmar - 0x02D6, // H-FOnewearl - 0x02D9, // H-FOnewm + 0x0001, // Orland + 0x0002, // Kranz + 0x0003, // Ino'lis + 0x0004, // Sil'fer + 0x0006, // Kylria + 0x0111, // Relmitos + 0x0112, // Viviana + 0x0115, // Glustar + 0x02AA, // H-HUmar + 0x02AB, // H-HUnewearl + 0x02AE, // H-RAmar + 0x02AF, // H-RAmarl + 0x02B2, // H-FOmar + 0x02B3, // H-FOmarl + 0x02B4, // H-FOnewm + 0x02B5, // H-FOnewearl + 0x02CC, // H-HUmar + 0x02CD, // H-RAmarl + 0x02CE, // H-FOmarl + 0x02CF, // H-HUnewearl + 0x02D1, // H-RAmarl + 0x02D5, // H-FOmar + 0x02D6, // H-FOnewearl + 0x02D9, // H-FOnewm }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_HU_CLASS_MALE_SC: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0113, // Teifu - 0x02AA, // H-HUmar - 0x02AC, // H-HUcast - 0x02CC, // H-HUmar - 0x02D7, // H-HUcast + 0x0001, // Orland + 0x0113, // Teifu + 0x02AA, // H-HUmar + 0x02AC, // H-HUcast + 0x02CC, // H-HUmar + 0x02D7, // H-HUcast }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_FEMALE_SC: { static const unordered_set card_ids = { - 0x0003, // Ino'lis - 0x0004, // Sil'fer - 0x0006, // Kylria - 0x0110, // Saligun - 0x0112, // Viviana - 0x0114, // Stella - 0x02AB, // H-HUnewearl - 0x02AD, // H-HUcaseal - 0x02AF, // H-RAmarl - 0x02B1, // H-RAcaseal - 0x02B3, // H-FOmarl - 0x02B5, // H-FOnewearl - 0x02CE, // H-FOmarl - 0x02CF, // H-HUnewearl - 0x02D1, // H-RAmarl - 0x02D4, // H-HUcaseal - 0x02D6, // H-FOnewearl - 0x02D8, // H-RAcaseal + 0x0003, // Ino'lis + 0x0004, // Sil'fer + 0x0006, // Kylria + 0x0110, // Saligun + 0x0112, // Viviana + 0x0114, // Stella + 0x02AB, // H-HUnewearl + 0x02AD, // H-HUcaseal + 0x02AF, // H-RAmarl + 0x02B1, // H-RAcaseal + 0x02B3, // H-FOmarl + 0x02B5, // H-FOnewearl + 0x02CE, // H-FOmarl + 0x02CF, // H-HUnewearl + 0x02D1, // H-RAmarl + 0x02D4, // H-HUcaseal + 0x02D6, // H-FOnewearl + 0x02D8, // H-RAcaseal }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_HU_OR_FO_CLASS_HUMAN_SC: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0003, // Ino'lis - 0x0004, // Sil'fer - 0x0111, // Relmitos - 0x0115, // Glustar - 0x0112, // Viviana - 0x02AA, // H-HUmar - 0x02AB, // H-HUnewearl - 0x02B2, // H-FOmar - 0x02B3, // H-FOmarl - 0x02B4, // H-FOnewm - 0x02B5, // H-FOnewearl - 0x02CC, // H-HUmar - 0x02CE, // H-FOmarl - 0x02CF, // H-HUnewearl - 0x02D5, // H-FOmar - 0x02D6, // H-FOnewearl - 0x02D9, // H-FOnewm + 0x0001, // Orland + 0x0003, // Ino'lis + 0x0004, // Sil'fer + 0x0111, // Relmitos + 0x0115, // Glustar + 0x0112, // Viviana + 0x02AA, // H-HUmar + 0x02AB, // H-HUnewearl + 0x02B2, // H-FOmar + 0x02B3, // H-FOmarl + 0x02B4, // H-FOnewm + 0x02B5, // H-FOnewearl + 0x02CC, // H-HUmar + 0x02CE, // H-FOmarl + 0x02CF, // H-HUnewearl + 0x02D5, // H-FOmar + 0x02D6, // H-FOnewearl + 0x02D9, // H-FOnewm }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_HU_CLASS_ANDROID_SC: { static const unordered_set card_ids = { - 0x0110, // Saligun - 0x0113, // Teifu - 0x02AC, // H-HUcast - 0x02AD, // H-HUcaseal - 0x02D4, // H-HUcaseal - 0x02D7, // H-HUcast + 0x0110, // Saligun + 0x0113, // Teifu + 0x02AC, // H-HUcast + 0x02AD, // H-HUcaseal + 0x02D4, // H-HUcaseal + 0x02D7, // H-HUcast }; return ret && card_ids.count(card_id2); } case CriterionCode::UNKNOWN_10: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0003, // Ino'lis - 0x0110, // Saligun - 0x0111, // Relmitos - 0x0113, // Teifu - 0x02AA, // H-HUmar - 0x02AC, // H-HUcast - 0x02AD, // H-HUcaseal - 0x02B2, // H-FOmar - 0x02B3, // H-FOmarl - 0x02CC, // H-HUmar - 0x02CE, // H-FOmarl - 0x02D4, // H-HUcaseal - 0x02D5, // H-FOmar - 0x02D7, // H-HUcast + 0x0001, // Orland + 0x0003, // Ino'lis + 0x0110, // Saligun + 0x0111, // Relmitos + 0x0113, // Teifu + 0x02AA, // H-HUmar + 0x02AC, // H-HUcast + 0x02AD, // H-HUcaseal + 0x02B2, // H-FOmar + 0x02B3, // H-FOmarl + 0x02CC, // H-HUmar + 0x02CE, // H-FOmarl + 0x02D4, // H-HUcaseal + 0x02D5, // H-FOmar + 0x02D7, // H-HUcast }; return ret && card_ids.count(card_id2); } case CriterionCode::UNKNOWN_11: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0002, // Kranz - 0x0005, // Guykild - 0x0113, // Teifu - 0x02AA, // H-HUmar - 0x02AC, // H-HUcast - 0x02AE, // H-RAmar - 0x02B0, // H-RAcast - 0x02CC, // H-HUmar - 0x02CD, // H-RAmarl - 0x02D0, // H-RAcast - 0x02D7, // H-HUcast + 0x0001, // Orland + 0x0002, // Kranz + 0x0005, // Guykild + 0x0113, // Teifu + 0x02AA, // H-HUmar + 0x02AC, // H-HUcast + 0x02AE, // H-RAmar + 0x02B0, // H-RAcast + 0x02CC, // H-HUmar + 0x02CD, // H-RAmarl + 0x02D0, // H-RAcast + 0x02D7, // H-HUcast }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_HUNEWEARL_CLASS_SC: { static const unordered_set card_ids = { - 0x0004, // Sil'fer - 0x02AB, // H-HUnewearl - 0x02CF, // H-HUnewearl + 0x0004, // Sil'fer + 0x02AB, // H-HUnewearl + 0x02CF, // H-HUnewearl }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_RA_CLASS_MALE_SC: { static const unordered_set card_ids = { - 0x0002, // Kranz - 0x0005, // Guykild - 0x02AE, // H-RAmar - 0x02B0, // H-RAcast - 0x02CD, // H-RAmarl - 0x02D0, // H-RAcast + 0x0002, // Kranz + 0x0005, // Guykild + 0x02AE, // H-RAmar + 0x02B0, // H-RAcast + 0x02CD, // H-RAmarl + 0x02D0, // H-RAcast }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_RA_CLASS_FEMALE_SC: { static const unordered_set card_ids = { - 0x0006, // Kylria - 0x0114, // Stella - 0x02AF, // H-RAmarl - 0x02B1, // H-RAcaseal - 0x02D1, // H-RAmarl - 0x02D2, // D-RAcaseal + 0x0006, // Kylria + 0x0114, // Stella + 0x02AF, // H-RAmarl + 0x02B1, // H-RAcaseal + 0x02D1, // H-RAmarl + 0x02D2, // D-RAcaseal }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_RA_OR_FO_CLASS_FEMALE_SC: { static const unordered_set card_ids = { - 0x0003, // Ino'lis - 0x0006, // Kylria - 0x0112, // Viviana - 0x0114, // Stella - 0x02AF, // H-RAmarl - 0x02B1, // H-RAcaseal - 0x02B3, // H-FOmarl - 0x02B5, // H-FOnewearl - 0x02CE, // H-FOmarl - 0x02D1, // H-RAmarl - 0x02D6, // H-FOnewearl - 0x02D8, // H-RAcaseal + 0x0003, // Ino'lis + 0x0006, // Kylria + 0x0112, // Viviana + 0x0114, // Stella + 0x02AF, // H-RAmarl + 0x02B1, // H-RAcaseal + 0x02B3, // H-FOmarl + 0x02B5, // H-FOnewearl + 0x02CE, // H-FOmarl + 0x02D1, // H-RAmarl + 0x02D6, // H-FOnewearl + 0x02D8, // H-RAcaseal }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_HU_OR_RA_CLASS_HUMAN_SC: { static const unordered_set card_ids = { - 0x0001, // Orland - 0x0002, // Kranz - 0x0004, // Sil'fer - 0x0006, // Kylria - 0x02AA, // H-HUmar - 0x02AB, // H-HUnewearl - 0x02AE, // H-RAmar - 0x02AF, // H-RAmarl - 0x02CC, // H-HUmar - 0x02CD, // H-RAmarl - 0x02CF, // H-HUnewearl - 0x02D1, // H-RAmarl + 0x0001, // Orland + 0x0002, // Kranz + 0x0004, // Sil'fer + 0x0006, // Kylria + 0x02AA, // H-HUmar + 0x02AB, // H-HUnewearl + 0x02AE, // H-RAmar + 0x02AF, // H-RAmarl + 0x02CC, // H-HUmar + 0x02CD, // H-RAmarl + 0x02CF, // H-HUnewearl + 0x02D1, // H-RAmarl }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_RA_CLASS_ANDROID_SC: { static const unordered_set card_ids = { - 0x0005, // Guykild - 0x0114, // Stella - 0x02B0, // H-RAcast - 0x02B1, // H-RAcaseal - 0x02D0, // H-RAcast - 0x02D8, // H-RAcaseal + 0x0005, // Guykild + 0x0114, // Stella + 0x02B0, // H-RAcast + 0x02B1, // H-RAcaseal + 0x02D0, // H-RAcast + 0x02D8, // H-RAcaseal }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_FO_CLASS_FEMALE_SC: { static const unordered_set card_ids = { - 0x0003, // Ino'lis - 0x0112, // Viviana - 0x02B3, // H-FOmarl - 0x02B5, // H-FOnewearl - 0x02CE, // H-FOmarl - 0x02D6, // H-FOnewearl + 0x0003, // Ino'lis + 0x0112, // Viviana + 0x02B3, // H-FOmarl + 0x02B5, // H-FOnewearl + 0x02CE, // H-FOmarl + 0x02D6, // H-FOnewearl }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_FEMALE_HUMAN_SC: { static const unordered_set card_ids = { - 0x0003, // Ino'lis - 0x0004, // Sil'fer - 0x0006, // Kylria - 0x0112, // Viviana - 0x02AB, // H-HUnewearl - 0x02AF, // H-RAmarl - 0x02B3, // H-FOmarl - 0x02B5, // H-FOnewearl - 0x02CE, // H-FOmarl - 0x02CF, // H-HUnewearl - 0x02D1, // H-RAmarl - 0x02D6, // H-FOnewearl + 0x0003, // Ino'lis + 0x0004, // Sil'fer + 0x0006, // Kylria + 0x0112, // Viviana + 0x02AB, // H-HUnewearl + 0x02AF, // H-RAmarl + 0x02B3, // H-FOmarl + 0x02B5, // H-FOnewearl + 0x02CE, // H-FOmarl + 0x02CF, // H-HUnewearl + 0x02D1, // H-RAmarl + 0x02D6, // H-FOnewearl }; return ret && card_ids.count(card_id2); } case CriterionCode::HUNTER_ANDROID_SC: { static const unordered_set card_ids = { - 0x0005, // Guykild - 0x0110, // Saligun - 0x0113, // Teifu - 0x0114, // Stella - 0x02AC, // H-HUcast - 0x02AD, // H-HUcaseal - 0x02B0, // H-RAcast - 0x02B1, // H-RAcaseal - 0x02D0, // H-RAcast - 0x02D4, // H-HUcaseal - 0x02D7, // H-HUcast - 0x02D8, // H-RAcaseal + 0x0005, // Guykild + 0x0110, // Saligun + 0x0113, // Teifu + 0x0114, // Stella + 0x02AC, // H-HUcast + 0x02AD, // H-HUcaseal + 0x02B0, // H-RAcast + 0x02B1, // H-RAcaseal + 0x02D0, // H-RAcast + 0x02D4, // H-HUcaseal + 0x02D7, // H-HUcast + 0x02D8, // H-RAcaseal }; return ret && card_ids.count(card_id2); } @@ -1368,7 +1363,7 @@ uint16_t RulerServer::compute_attack_or_defense_costs( if (((action_type == ActionType::ATTACK) || (action_type == ActionType::INVALID_00)) && (this->find_condition_on_card_ref(pa.attacker_card_ref, ConditionType::BIG_SWING) || - this->find_condition_on_card_ref(sc_card_ref_if_item, ConditionType::BIG_SWING))) { + this->find_condition_on_card_ref(sc_card_ref_if_item, ConditionType::BIG_SWING))) { cost_bias++; } @@ -1435,7 +1430,8 @@ bool RulerServer::compute_effective_range_and_target_mode_for_attack( TargetMode* out_effective_target_mode, uint16_t* out_orig_card_ref) const { size_t z; - for (z = 0; (z < 9) && (pa.action_card_refs[z] != 0xFFFF); z++) { } + for (z = 0; (z < 9) && (pa.action_card_refs[z] != 0xFFFF); z++) { + } if (z >= 9) { return false; } @@ -1705,7 +1701,7 @@ int32_t RulerServer::error_code_for_client_setting_card( if ((short_statuses->at(0).card_ref == 0xFFFF) || !this->card_exists_by_status(short_statuses->at(0)) || !this->check_usability_or_apply_condition_for_card_refs( - card_ref, short_statuses->at(0).card_ref, 0xFFFF, 0xFF, AttackMedium::INVALID_FF)) { + card_ref, short_statuses->at(0).card_ref, 0xFFFF, 0xFF, AttackMedium::INVALID_FF)) { return -0x75; } @@ -1764,7 +1760,7 @@ int32_t RulerServer::error_code_for_client_setting_card( Location summon_area_loc; uint8_t summon_area_size; if (!this->get_creature_summon_area( - client_id, &summon_area_loc, &summon_area_size)) { + client_id, &summon_area_loc, &summon_area_size)) { if (team_id != 1) { if ((loc->x > 0) && (loc->x < this->map_and_rules->map.width - 1)) { if ((loc->y < this->map_and_rules->map.height - summon_cost - 1) && @@ -1984,7 +1980,8 @@ shared_ptr RulerServer::definition_for_card_id( uint32_t RulerServer::get_card_id_with_effective_range( uint16_t card_ref, uint16_t card_id_override, TargetMode* out_target_mode) const { uint16_t card_id = (card_id_override == 0xFFFF) - ? this->card_id_for_card_ref(card_ref) : card_id_override; + ? this->card_id_for_card_ref(card_ref) + : card_id_override; if (card_id != 0xFFFF) { auto ce = this->definition_for_card_id(card_id); @@ -2102,7 +2099,7 @@ bool RulerServer::get_move_path_length_and_cost( parray visited_map; path.end_loc = loc; if (!this->check_move_path_and_get_cost( - client_id, card_ref, &visited_map, &path, out_cost)) { + client_id, card_ref, &visited_map, &path, out_cost)) { return false; } @@ -2189,9 +2186,9 @@ bool RulerServer::is_attack_valid(const ActionState& pa) { (attacker_chain->chain.acting_card_ref != attacker_card_ref) || !attacker_ce || ((attacker_ce->def.type != CardType::HUNTERS_SC && - (attacker_ce->def.type != CardType::ARKZ_SC) && - (attacker_ce->def.type != CardType::CREATURE) && - (attacker_ce->def.type != CardType::ITEM)))) { + (attacker_ce->def.type != CardType::ARKZ_SC) && + (attacker_ce->def.type != CardType::CREATURE) && + (attacker_ce->def.type != CardType::ITEM)))) { this->error_code3 = -0x6F; return false; } @@ -2247,7 +2244,7 @@ bool RulerServer::is_attack_valid(const ActionState& pa) { } if (!this->check_usability_or_apply_condition_for_card_refs( - right_card_ref, attacker_card_ref, 0xFFFF, 0xFF, AttackMedium::INVALID_FF)) { + right_card_ref, attacker_card_ref, 0xFFFF, 0xFF, AttackMedium::INVALID_FF)) { this->error_code3 = -0x6A; return false; } @@ -2377,7 +2374,7 @@ bool RulerServer::is_defense_valid(const ActionState& pa) { } if (!this->defense_card_can_apply_to_attack( - pa.action_card_refs[0], pa.target_card_refs[0], pa.original_attacker_card_ref)) { + pa.action_card_refs[0], pa.target_card_refs[0], pa.original_attacker_card_ref)) { this->error_code3 = -0x61; return false; } @@ -2447,10 +2444,10 @@ size_t RulerServer::max_move_distance_for_card_ref(uint32_t card_ref) const { } RulerServer::MovePath::MovePath() - : length(-1), - remaining_distance(0), - num_occupied_tiles(0), - cost(0) { } + : length(-1), + remaining_distance(0), + num_occupied_tiles(0), + cost(0) {} void RulerServer::MovePath::add_step(const Location& loc) { this->step_locs[++this->length] = loc; @@ -2617,8 +2614,8 @@ const CardShortStatus* RulerServer::short_status_for_card_ref(uint16_t card_ref) bool RulerServer::should_allow_attacks_on_current_turn() const { return (this->state_flags && - ((this->state_flags->turn_num > 1) || - (this->state_flags->current_team_turn1 != this->state_flags->first_team_turn))); + ((this->state_flags->turn_num > 1) || + (this->state_flags->current_team_turn1 != this->state_flags->first_team_turn))); } int32_t RulerServer::verify_deck( @@ -2676,6 +2673,4 @@ int32_t RulerServer::verify_deck( return 0; } - - } // namespace Episode3 diff --git a/src/Episode3/RulerServer.hh b/src/Episode3/RulerServer.hh index ae2945df..491139c2 100644 --- a/src/Episode3/RulerServer.hh +++ b/src/Episode3/RulerServer.hh @@ -4,15 +4,13 @@ #include -#include "DataIndex.hh" -#include "PlayerState.hh" -#include "DeckState.hh" #include "AssistServer.hh" +#include "DataIndex.hh" +#include "DeckState.hh" +#include "PlayerState.hh" namespace Episode3 { - - class Server; void compute_effective_range( @@ -227,6 +225,4 @@ public: int32_t error_code3; }; - - } // namespace Episode3 diff --git a/src/Episode3/Server.cc b/src/Episode3/Server.cc index 51b6ba94..d9c3ac18 100644 --- a/src/Episode3/Server.cc +++ b/src/Episode3/Server.cc @@ -1,7 +1,7 @@ #include "Server.hh" -#include #include +#include #include "../SendCommands.hh" @@ -9,15 +9,11 @@ using namespace std; namespace Episode3 { - - -// These strings in the original implementation did not contain the semicolons -// (or anything after them). +// This is (obviously) not the original string. The original string is: +// "[V1][FINAL2.0] 03/09/13 15:30 by K.Toya" static const char* VERSION_SIGNATURE = "newserv Ep3 based on [V1][FINAL2.0] 03/09/13 15:30 by K.Toya"; - - ServerBase::PresenceEntry::PresenceEntry() { this->clear(); } @@ -28,19 +24,17 @@ void ServerBase::PresenceEntry::clear() { this->is_cpu_player = 0; } - - ServerBase::ServerBase( shared_ptr lobby, shared_ptr data_index, uint32_t random_seed, shared_ptr map_if_tournament) - : lobby(lobby), - data_index(data_index), - log(lobby->log.prefix + "[Ep3::Server] "), - random_seed(random_seed), - is_tournament(!!map_if_tournament), - last_chosen_map(map_if_tournament) { } + : lobby(lobby), + data_index(data_index), + log(lobby->log.prefix + "[Ep3::Server] "), + random_seed(random_seed), + is_tournament(!!map_if_tournament), + last_chosen_map(map_if_tournament) {} void ServerBase::init() { this->reset(); @@ -65,46 +59,44 @@ void ServerBase::recreate_server() { this->server->init(); } - - Server::Server(shared_ptr base) - : w_base(base), - battle_finished(false), - battle_in_progress(false), - round_num(1), - battle_phase(BattlePhase::INVALID_00), - first_team_turn(0xFF), - current_team_turn1(0xFF), - setup_phase(SetupPhase::REGISTRATION), - registration_phase(RegistrationPhase::AWAITING_NUM_PLAYERS), - action_subphase(ActionSubphase::ATTACK), - current_team_turn2(0xFF), - num_pending_attacks(0), - client_done_enqueuing_attacks(false), - player_ready_to_end_phase(false), - unknown_a10(0), - overall_time_expired(false), - battle_start_usecs(0), - should_copy_prev_states_to_current_states(0), - card_special(nullptr), - clients_done_in_mulligan_phase(false), - num_pending_attacks_with_cards(0), - unknown_a14(0), - unknown_a15(0), - defense_list_ended_for_client(false), - next_assist_card_set_number(1), - team_exp(0), - team_dice_boost(0), - team_client_count(0), - team_num_ally_fcs_destroyed(0), - team_num_cards_destroyed(0), - hard_reset_flag(false), - tournament_flag(base->is_tournament ? 1 : 0), - num_trap_tiles_of_type(0), - chosen_trap_tile_index_of_type(0), - has_done_pb(0), - num_6xB4x06_commands_sent(0), - prev_num_6xB4x06_commands_sent(0) { } + : w_base(base), + battle_finished(false), + battle_in_progress(false), + round_num(1), + battle_phase(BattlePhase::INVALID_00), + first_team_turn(0xFF), + current_team_turn1(0xFF), + setup_phase(SetupPhase::REGISTRATION), + registration_phase(RegistrationPhase::AWAITING_NUM_PLAYERS), + action_subphase(ActionSubphase::ATTACK), + current_team_turn2(0xFF), + num_pending_attacks(0), + client_done_enqueuing_attacks(false), + player_ready_to_end_phase(false), + unknown_a10(0), + overall_time_expired(false), + battle_start_usecs(0), + should_copy_prev_states_to_current_states(0), + card_special(nullptr), + clients_done_in_mulligan_phase(false), + num_pending_attacks_with_cards(0), + unknown_a14(0), + unknown_a15(0), + defense_list_ended_for_client(false), + next_assist_card_set_number(1), + team_exp(0), + team_dice_boost(0), + team_client_count(0), + team_num_ally_fcs_destroyed(0), + team_num_cards_destroyed(0), + hard_reset_flag(false), + tournament_flag(base->is_tournament ? 1 : 0), + num_trap_tiles_of_type(0), + chosen_trap_tile_index_of_type(0), + has_done_pb(0), + num_6xB4x06_commands_sent(0), + prev_num_6xB4x06_commands_sent(0) {} void Server::init() { this->card_special.reset(new CardSpecial(this->shared_from_this())); @@ -262,8 +254,7 @@ void Server::send_commands_for_joining_spectator(Channel& c) const { } } -__attribute__((format(printf, 2, 3))) -void Server::log_debug(const char* fmt, ...) const { +__attribute__((format(printf, 2, 3))) void Server::log_debug(const char* fmt, ...) const { auto l = this->base()->lobby.lock(); if (l && (this->base()->data_index->behavior_flags & Episode3::BehaviorFlag::ENABLE_STATUS_MESSAGES)) { va_list va; @@ -273,8 +264,7 @@ void Server::log_debug(const char* fmt, ...) const { } } -__attribute__((format(printf, 2, 3))) -void Server::send_debug_message_printf(const char* fmt, ...) const { +__attribute__((format(printf, 2, 3))) void Server::send_debug_message_printf(const char* fmt, ...) const { auto l = this->base()->lobby.lock(); if (l && (this->base()->data_index->behavior_flags & Episode3::BehaviorFlag::ENABLE_STATUS_MESSAGES)) { va_list va; @@ -286,8 +276,7 @@ void Server::send_debug_message_printf(const char* fmt, ...) const { } } -__attribute__((format(printf, 2, 3))) -void Server::send_info_message_printf(const char* fmt, ...) const { +__attribute__((format(printf, 2, 3))) void Server::send_info_message_printf(const char* fmt, ...) const { auto l = this->base()->lobby.lock(); if (l) { va_list va; @@ -539,7 +528,8 @@ void Server::check_for_destroyed_cards_and_send_6xB4x05_6xB4x02() { bool Server::check_presence_entry(uint8_t client_id) const { return (client_id < 4) - ? this->base()->presence_entries[client_id].player_present : false; + ? this->base()->presence_entries[client_id].player_present + : false; } void Server::clear_player_flags_after_dice_phase() { @@ -1220,7 +1210,6 @@ void Server::set_client_id_ready_to_advance_phase(uint8_t client_id) { } } - void Server::set_phase_after() { for (size_t client_id = 0; client_id < 4; client_id++) { auto ps = this->player_states[client_id]; @@ -1513,29 +1502,29 @@ bool Server::update_registration_phase() { } const unordered_map Server::subcommand_handlers({ - {0x0B, &Server::handle_6xB3x0B_mulligan_hand}, - {0x0C, &Server::handle_6xB3x0C_end_mulligan_phase}, - {0x0D, &Server::handle_6xB3x0D_end_non_action_phase}, - {0x0E, &Server::handle_6xB3x0E_discard_card_from_hand}, - {0x0F, &Server::handle_6xB3x0F_set_card_from_hand}, - {0x10, &Server::handle_6xB3x10_move_fc_to_location}, - {0x11, &Server::handle_6xB3x11_enqueue_attack_or_defense}, - {0x12, &Server::handle_6xB3x12_end_attack_list}, - {0x13, &Server::handle_6xB3x13_update_map_during_setup}, - {0x14, &Server::handle_6xB3x14_update_deck_during_setup}, - {0x15, &Server::handle_6xB3x15_unused_hard_reset_server_state}, - {0x1B, &Server::handle_6xB3x1B_update_player_name}, - {0x1D, &Server::handle_6xB3x1D_start_battle}, - {0x21, &Server::handle_6xB3x21_end_battle}, - {0x28, &Server::handle_6xB3x28_end_defense_list}, - {0x2B, &Server::handle_6xB3x2B_ignored}, - {0x34, &Server::handle_6xB3x34_subtract_ally_atk_points}, - {0x37, &Server::handle_6xB3x37_client_ready_to_advance_from_starter_roll_phase}, - {0x3A, &Server::handle_6xB3x3A_ignored}, - {0x40, &Server::handle_6xB3x40_map_list_request}, - {0x41, &Server::handle_6xB3x41_map_request}, - {0x48, &Server::handle_6xB3x48_end_turn}, - {0x49, &Server::handle_6xB3x49_card_counts}, + {0x0B, &Server::handle_6xB3x0B_mulligan_hand}, + {0x0C, &Server::handle_6xB3x0C_end_mulligan_phase}, + {0x0D, &Server::handle_6xB3x0D_end_non_action_phase}, + {0x0E, &Server::handle_6xB3x0E_discard_card_from_hand}, + {0x0F, &Server::handle_6xB3x0F_set_card_from_hand}, + {0x10, &Server::handle_6xB3x10_move_fc_to_location}, + {0x11, &Server::handle_6xB3x11_enqueue_attack_or_defense}, + {0x12, &Server::handle_6xB3x12_end_attack_list}, + {0x13, &Server::handle_6xB3x13_update_map_during_setup}, + {0x14, &Server::handle_6xB3x14_update_deck_during_setup}, + {0x15, &Server::handle_6xB3x15_unused_hard_reset_server_state}, + {0x1B, &Server::handle_6xB3x1B_update_player_name}, + {0x1D, &Server::handle_6xB3x1D_start_battle}, + {0x21, &Server::handle_6xB3x21_end_battle}, + {0x28, &Server::handle_6xB3x28_end_defense_list}, + {0x2B, &Server::handle_6xB3x2B_ignored}, + {0x34, &Server::handle_6xB3x34_subtract_ally_atk_points}, + {0x37, &Server::handle_6xB3x37_client_ready_to_advance_from_starter_roll_phase}, + {0x3A, &Server::handle_6xB3x3A_ignored}, + {0x40, &Server::handle_6xB3x40_map_list_request}, + {0x41, &Server::handle_6xB3x41_map_request}, + {0x48, &Server::handle_6xB3x48_end_turn}, + {0x49, &Server::handle_6xB3x49_card_counts}, }); void Server::on_server_data_input(const string& data) { @@ -2025,7 +2014,7 @@ void Server::handle_6xB3x28_end_defense_list(const string& data) { this->send(out_cmd_fin); } -void Server::handle_6xB3x2B_ignored(const string&) { } +void Server::handle_6xB3x2B_ignored(const string&) {} void Server::handle_6xB3x34_subtract_ally_atk_points(const string& data) { const auto& in_cmd = check_size_t(data); @@ -2131,7 +2120,7 @@ void Server::handle_6xB3x37_client_ready_to_advance_from_starter_roll_phase(cons } } -void Server::handle_6xB3x3A_ignored(const string&) { } +void Server::handle_6xB3x3A_ignored(const string&) {} void Server::handle_6xB3x40_map_list_request(const string& data) { const auto& in_cmd = check_size_t(data); @@ -2379,7 +2368,7 @@ void Server::unknown_8023EEF4() { if (!this->attack_cards[this->unknown_a14]->action_chain.check_flag(0x40)) { this->card_special->unknown_8024945C(this->attack_cards[this->unknown_a14], as); } - this->attack_cards[this->unknown_a14]->compute_action_chain_results(1,0); + this->attack_cards[this->unknown_a14]->compute_action_chain_results(1, 0); this->attack_cards[this->unknown_a14]->unknown_80236374(this->attack_cards[this->unknown_a14], &as); if (!this->attack_cards[this->unknown_a14]->action_chain.check_flag(0x40)) { this->card_special->unknown_8024966C(this->attack_cards[this->unknown_a14], &as); @@ -2653,7 +2642,6 @@ void Server::send_6xB4x05() { this->send(cmd); } - void Server::send_6xB4x02_for_all_players_if_needed(bool always_send) { for (size_t z = 0; z < 4; z++) { auto ps = this->player_states[z]; @@ -2680,6 +2668,4 @@ void Server::send_6xB4x50_trap_tile_locations() const { this->send(this->prepare_6xB4x50_trap_tile_locations()); } - - } // namespace Episode3 diff --git a/src/Episode3/Server.hh b/src/Episode3/Server.hh index 1f031dc3..7e24ff46 100644 --- a/src/Episode3/Server.hh +++ b/src/Episode3/Server.hh @@ -4,9 +4,9 @@ #include -#include "../Text.hh" -#include "../CommandFormats.hh" #include "../Channel.hh" +#include "../CommandFormats.hh" +#include "../Text.hh" #include "AssistServer.hh" #include "CardSpecial.hh" #include "MapState.hh" @@ -17,8 +17,6 @@ struct Lobby; namespace Episode3 { - - /** * This implementation of Episode 3 battles (contained in all files in the * src/Episode3 directory, except for DataIndex.hh/cc) is derived from Sega's @@ -27,7 +25,7 @@ namespace Episode3 { * in these files map very closely to how their server implementation was * written; notable differences (due to necessary environment differences or bug * fixes) are described in the comments therein. - * + * * Some debugging functions have been added which are not part of the original * implementation. Notably, this applies to functions like debug message senders * and loggers and all str() functions. @@ -55,8 +53,6 @@ namespace Episode3 { class Server; - - class ServerBase : public std::enable_shared_from_this { public: ServerBase( @@ -122,13 +118,10 @@ public: void send_commands_for_joining_spectator(Channel& ch) const; - __attribute__((format(printf, 2, 3))) - void log_debug(const char* fmt, ...) const; + __attribute__((format(printf, 2, 3))) void log_debug(const char* fmt, ...) const; - __attribute__((format(printf, 2, 3))) - void send_debug_message_printf(const char* fmt, ...) const; - __attribute__((format(printf, 2, 3))) - void send_info_message_printf(const char* fmt, ...) const; + __attribute__((format(printf, 2, 3))) void send_debug_message_printf(const char* fmt, ...) const; + __attribute__((format(printf, 2, 3))) void send_info_message_printf(const char* fmt, ...) const; void send_debug_command_received_message( uint8_t client_id, uint8_t subsubcommand, const char* description) const; void send_debug_command_received_message( @@ -241,6 +234,7 @@ public: std::vector> const_cast_set_cards_v( const std::vector>& cards); + private: typedef void (Server::*handler_t)(const std::string&); static const std::unordered_map subcommand_handlers; @@ -301,6 +295,4 @@ public: mutable uint32_t prev_num_6xB4x06_commands_sent; }; - - } // namespace Episode3 diff --git a/src/Episode3/Tournament.cc b/src/Episode3/Tournament.cc index 5dadf6a0..9416c94d 100644 --- a/src/Episode3/Tournament.cc +++ b/src/Episode3/Tournament.cc @@ -9,14 +9,14 @@ using namespace std; namespace Episode3 { - - Tournament::PlayerEntry::PlayerEntry(uint32_t serial_number) - : serial_number(serial_number), com_deck() { } + : serial_number(serial_number), + com_deck() {} Tournament::PlayerEntry::PlayerEntry( shared_ptr com_deck) - : serial_number(0), com_deck(com_deck) { } + : serial_number(0), + com_deck(com_deck) {} bool Tournament::PlayerEntry::is_com() const { return (this->com_deck != nullptr); @@ -26,17 +26,15 @@ bool Tournament::PlayerEntry::is_human() const { return (this->serial_number != 0); } - - Tournament::Team::Team( shared_ptr tournament, size_t index, size_t max_players) - : tournament(tournament), - index(index), - max_players(max_players), - name(""), - password(""), - num_rounds_cleared(0), - is_active(true) { } + : tournament(tournament), + index(index), + max_players(max_players), + name(""), + password(""), + num_rounds_cleared(0), + is_active(true) {} string Tournament::Team::str() const { size_t num_human_players = 0; @@ -133,8 +131,8 @@ bool Tournament::Team::unregister_player(uint32_t serial_number) { } } - // If the tournament has not started yet, just remove the player from the - // team + // If the tournament has not started yet, just remove the player from the + // team } else { if (!tournament->all_player_serial_numbers.erase(serial_number)) { throw logic_error("player removed from team but not from tournament"); @@ -173,17 +171,15 @@ size_t Tournament::Team::num_com_players() const { return ret; } - - Tournament::Match::Match( shared_ptr tournament, shared_ptr preceding_a, shared_ptr preceding_b) - : tournament(tournament), - preceding_a(preceding_a), - preceding_b(preceding_b), - winner_team(nullptr), - round_num(0) { + : tournament(tournament), + preceding_a(preceding_a), + preceding_b(preceding_b), + winner_team(nullptr), + round_num(0) { if (this->preceding_a->round_num != this->preceding_b->round_num) { throw logic_error("preceding matches have different round numbers"); } @@ -193,11 +189,11 @@ Tournament::Match::Match( Tournament::Match::Match( shared_ptr tournament, shared_ptr winner_team) - : tournament(tournament), - preceding_a(nullptr), - preceding_b(nullptr), - winner_team(winner_team), - round_num(0) { } + : tournament(tournament), + preceding_a(nullptr), + preceding_b(nullptr), + winner_team(winner_team), + round_num(0) {} string Tournament::Match::str() const { string winner_str = this->winner_team ? this->winner_team->str() : "(none)"; @@ -216,7 +212,8 @@ bool Tournament::Match::resolve_if_no_human_players() { !this->preceding_a->winner_team->has_any_human_players() && !this->preceding_b->winner_team->has_any_human_players()) { this->set_winner_team((random_object() & 1) - ? this->preceding_b->winner_team : this->preceding_a->winner_team); + ? this->preceding_b->winner_team + : this->preceding_a->winner_team); return true; } else { return false; @@ -282,8 +279,6 @@ shared_ptr Tournament::Match::opponent_team_for_team( } } - - Tournament::Tournament( shared_ptr data_index, uint8_t number, @@ -292,15 +287,15 @@ Tournament::Tournament( const Rules& rules, size_t num_teams, bool is_2v2) - : log(string_printf("[Tournament/%02hhX] ", number)), - data_index(data_index), - number(number), - name(name), - map(map), - rules(rules), - num_teams(num_teams), - is_2v2(is_2v2), - current_state(State::REGISTRATION) { + : log(string_printf("[Tournament/%02hhX] ", number)), + data_index(data_index), + number(number), + name(name), + map(map), + rules(rules), + num_teams(num_teams), + is_2v2(is_2v2), + current_state(State::REGISTRATION) { if (this->num_teams < 4) { throw invalid_argument("team count must be 4 or more"); } @@ -316,11 +311,11 @@ Tournament::Tournament( std::shared_ptr data_index, uint8_t number, std::shared_ptr json) - : log(string_printf("[Tournament/%02hhX] ", number)), - data_index(data_index), - source_json(json), - number(number), - current_state(State::REGISTRATION) { } + : log(string_printf("[Tournament/%02hhX] ", number)), + data_index(data_index), + source_json(json), + number(number), + current_state(State::REGISTRATION) {} void Tournament::init() { vector team_index_to_rounds_cleared; @@ -414,10 +409,8 @@ void Tournament::init() { if (!match->preceding_a->winner_team || !match->preceding_b->winner_team) { throw logic_error("preceding matches are not resolved"); } - size_t& a_rounds_cleared = team_index_to_rounds_cleared[ - match->preceding_a->winner_team->index]; - size_t& b_rounds_cleared = team_index_to_rounds_cleared[ - match->preceding_b->winner_team->index]; + size_t& a_rounds_cleared = team_index_to_rounds_cleared[match->preceding_a->winner_team->index]; + size_t& b_rounds_cleared = team_index_to_rounds_cleared[match->preceding_b->winner_team->index]; if (a_rounds_cleared && b_rounds_cleared) { throw runtime_error("both teams won the same match"); } @@ -469,8 +462,7 @@ std::shared_ptr Tournament::json() const { dict.emplace("map_number", make_json_int(this->map->map.map_number)); dict.emplace("rules", this->rules.json()); dict.emplace("is_2v2", make_json_bool(this->is_2v2)); - dict.emplace("is_registration_complete", make_json_bool( - this->current_state != State::REGISTRATION)); + dict.emplace("is_registration_complete", make_json_bool(this->current_state != State::REGISTRATION)); vector> teams_list; for (auto team : this->teams) { @@ -661,13 +653,12 @@ void Tournament::print_bracket(FILE* stream) const { } } - - TournamentIndex::TournamentIndex( shared_ptr data_index, const string& state_filename, bool skip_load_state) - : data_index(data_index), state_filename(state_filename) { + : data_index(data_index), + state_filename(state_filename) { if (this->state_filename.empty() || skip_load_state) { return; } @@ -768,6 +759,4 @@ shared_ptr TournamentIndex::team_for_serial_number( return nullptr; } - - } // namespace Episode3 diff --git a/src/Episode3/Tournament.hh b/src/Episode3/Tournament.hh index 744091f7..9b5b0100 100644 --- a/src/Episode3/Tournament.hh +++ b/src/Episode3/Tournament.hh @@ -1,14 +1,14 @@ #pragma once -#include #include +#include #include -#include -#include -#include #include #include +#include +#include +#include #include "../Player.hh" @@ -18,8 +18,6 @@ namespace Episode3 { // The comment in Server.hh does not apply to this file (and Tournament.cc). - - class Tournament : public std::enable_shared_from_this { public: enum class State { @@ -172,11 +170,11 @@ public: std::vector> all_tournaments() const; std::shared_ptr create_tournament( - const std::string& name, - std::shared_ptr map, - const Rules& rules, - size_t num_teams, - bool is_2v2); + const std::string& name, + std::shared_ptr map, + const Rules& rules, + size_t num_teams, + bool is_2v2); void delete_tournament(uint8_t number); std::shared_ptr get_tournament(uint8_t number) const; std::shared_ptr get_tournament(const std::string& name) const; @@ -190,6 +188,4 @@ private: std::shared_ptr tournaments[0x20]; }; - - } // namespace Episode3 diff --git a/src/FileContentsCache.cc b/src/FileContentsCache.cc index 3e9ad133..ff846258 100644 --- a/src/FileContentsCache.cc +++ b/src/FileContentsCache.cc @@ -7,15 +7,15 @@ using namespace std; - - -FileContentsCache::FileContentsCache(uint64_t ttl_usecs) : ttl_usecs(ttl_usecs) { } +FileContentsCache::FileContentsCache(uint64_t ttl_usecs) : ttl_usecs(ttl_usecs) {} FileContentsCache::File::File( const string& name, string&& data, uint64_t load_time) - : name(name), data(new string(move(data))), load_time(load_time) { } + : name(name), + data(new string(move(data))), + load_time(load_time) {} shared_ptr FileContentsCache::replace( const string& name, string&& data, uint64_t t) { @@ -65,7 +65,8 @@ FileContentsCache::GetResult FileContentsCache::get(const std::string& name, if (this->ttl_usecs && (t - entry->load_time < this->ttl_usecs)) { return {entry, false}; } - } catch (const out_of_range& e) { } + } catch (const out_of_range& e) { + } return {this->replace(name, generate(name)), true}; } diff --git a/src/FileContentsCache.hh b/src/FileContentsCache.hh index 39ea8109..74d76256 100644 --- a/src/FileContentsCache.hh +++ b/src/FileContentsCache.hh @@ -1,15 +1,14 @@ #pragma once +#include #include #include #include -#include #include using namespace std; - class FileContentsCache { public: struct File { @@ -92,7 +91,8 @@ public: if (this->ttl_usecs && (t - f->load_time < this->ttl_usecs)) { return {*reinterpret_cast(f->data->data()), f, false}; } - } catch (const out_of_range& e) { } + } catch (const out_of_range& e) { + } T value = generate(name); auto ret = this->replace_obj(name, value); ret.generate_called = true; diff --git a/src/FunctionCompiler.cc b/src/FunctionCompiler.cc index 07cba109..8719e8e4 100644 --- a/src/FunctionCompiler.cc +++ b/src/FunctionCompiler.cc @@ -3,20 +3,18 @@ #include #include -#include #include +#include #ifdef HAVE_RESOURCE_FILE #include #endif -#include "Loggers.hh" #include "CommandFormats.hh" +#include "Loggers.hh" using namespace std; - - bool function_compiler_available() { #ifndef HAVE_RESOURCE_FILE return false; @@ -25,8 +23,6 @@ bool function_compiler_available() { #endif } - - const char* name_for_architecture(CompiledFunctionCode::Architecture arch) { switch (arch) { case CompiledFunctionCode::Architecture::POWERPC: @@ -38,12 +34,10 @@ const char* name_for_architecture(CompiledFunctionCode::Architecture arch) { } } - - template string CompiledFunctionCode::generate_client_command_t( - const unordered_map& label_writes, - const string& suffix) const { + const unordered_map& label_writes, + const string& suffix) const { FooterT footer; footer.num_relocations = this->relocation_deltas.size(); footer.unused1.clear(0); @@ -82,8 +76,8 @@ string CompiledFunctionCode::generate_client_command_t( } string CompiledFunctionCode::generate_client_command( - const unordered_map& label_writes, - const string& suffix) const { + const unordered_map& label_writes, + const string& suffix) const { if (this->arch == Architecture::POWERPC) { return this->generate_client_command_t( label_writes, suffix); @@ -99,8 +93,6 @@ bool CompiledFunctionCode::is_big_endian() const { return this->arch == Architecture::POWERPC; } - - shared_ptr compile_function_code( CompiledFunctionCode::Architecture arch, const string& directory, @@ -159,8 +151,6 @@ shared_ptr compile_function_code( #endif } - - FunctionCodeIndex::FunctionCodeIndex(const string& directory) { if (!function_compiler_available()) { function_compiler_log.info("Function compiler is not available"); @@ -217,8 +207,6 @@ vector FunctionCodeIndex::patch_menu() const { return ret; } - - DOLFileIndex::DOLFileIndex(const string& directory) { if (!function_compiler_available()) { function_compiler_log.info("Function compiler is not available"); diff --git a/src/FunctionCompiler.hh b/src/FunctionCompiler.hh index b7f94d4c..eb8cb981 100644 --- a/src/FunctionCompiler.hh +++ b/src/FunctionCompiler.hh @@ -2,20 +2,16 @@ #include +#include +#include #include #include -#include #include -#include #include "Menu.hh" - - bool function_compiler_available(); - - // TODO: Support x86 and SH4 function calls in the future. Currently we only // support PPC32 because I haven't written an appropriate x86 assembler yet. @@ -39,8 +35,8 @@ struct CompiledFunctionCode { template std::string generate_client_command_t( - const std::unordered_map& label_writes, - const std::string& suffix) const; + const std::unordered_map& label_writes, + const std::string& suffix) const; std::string generate_client_command( const std::unordered_map& label_writes = {}, const std::string& suffix = "") const; @@ -54,8 +50,6 @@ std::shared_ptr compile_function_code( const std::string& name, const std::string& text); - - struct FunctionCodeIndex { FunctionCodeIndex() = default; explicit FunctionCodeIndex(const std::string& directory); @@ -72,8 +66,6 @@ struct FunctionCodeIndex { } }; - - struct DOLFileIndex { struct DOLFile { uint32_t menu_item_id; diff --git a/src/GSLArchive.cc b/src/GSLArchive.cc index abdabcdc..ce40efde 100644 --- a/src/GSLArchive.cc +++ b/src/GSLArchive.cc @@ -8,8 +8,6 @@ using namespace std; - - template struct GSLHeaderEntry { using U32T = typename std::conditional::type; @@ -38,7 +36,7 @@ void GSLArchive::load_t() { } GSLArchive::GSLArchive(shared_ptr data, bool big_endian) - : data(data) { + : data(data) { if (big_endian) { this->load_t(); } else { diff --git a/src/GSLArchive.hh b/src/GSLArchive.hh index 48453506..db77c7e6 100644 --- a/src/GSLArchive.hh +++ b/src/GSLArchive.hh @@ -8,8 +8,6 @@ #include #include - - class GSLArchive { public: GSLArchive(std::shared_ptr data, bool big_endian); diff --git a/src/IPFrameInfo.cc b/src/IPFrameInfo.cc index 535936e6..c0e241ec 100644 --- a/src/IPFrameInfo.cc +++ b/src/IPFrameInfo.cc @@ -6,8 +6,6 @@ using namespace std; - - static inline uint16_t collapse_checksum(uint32_t sum) { // It's impossible for this to be necessary more than twice: the first // addition can carry out at most a single bit. @@ -15,35 +13,33 @@ static inline uint16_t collapse_checksum(uint32_t sum) { return (sum & 0xFFFF) + (sum >> 16); } - - FrameInfo::FrameInfo() - : ether(nullptr), - ether_protocol(0), - ipv4(nullptr), - arp(nullptr), - udp(nullptr), - tcp(nullptr), - header_start(nullptr), - payload(nullptr), - total_size(0), - tcp_options_size(0), - payload_size(0) { } + : ether(nullptr), + ether_protocol(0), + ipv4(nullptr), + arp(nullptr), + udp(nullptr), + tcp(nullptr), + header_start(nullptr), + payload(nullptr), + total_size(0), + tcp_options_size(0), + payload_size(0) {} -FrameInfo::FrameInfo(const string& data) : FrameInfo(data.data(), data.size()) { } +FrameInfo::FrameInfo(const string& data) : FrameInfo(data.data(), data.size()) {} FrameInfo::FrameInfo(const void* header_start, size_t size) - : ether(nullptr), - ether_protocol(0), - ipv4(nullptr), - arp(nullptr), - udp(nullptr), - tcp(nullptr), - header_start(header_start), - payload(nullptr), - total_size(size), - tcp_options_size(0), - payload_size(size) { + : ether(nullptr), + ether_protocol(0), + ipv4(nullptr), + arp(nullptr), + udp(nullptr), + tcp(nullptr), + header_start(header_start), + payload(nullptr), + total_size(size), + tcp_options_size(0), + payload_size(size) { // Parse ethernet header if (this->payload_size < sizeof(EthernetHeader)) { @@ -125,26 +121,31 @@ string FrameInfo::header_str() const { return ""; } - string ret = string_printf("%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX->%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", + string ret = string_printf( + "%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX->%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", this->ether->src_mac[0], this->ether->src_mac[1], this->ether->src_mac[2], this->ether->src_mac[3], this->ether->src_mac[4], this->ether->src_mac[5], this->ether->dest_mac[0], this->ether->dest_mac[1], this->ether->dest_mac[2], this->ether->dest_mac[3], this->ether->dest_mac[4], this->ether->dest_mac[5]); if (this->arp) { - ret += string_printf(",ARP,hw_type=%04hX,proto_type=%04hX,hw_addr_len=%02hhX,proto_addr_len=%02hhX,op=%04hX", + ret += string_printf( + ",ARP,hw_type=%04hX,proto_type=%04hX,hw_addr_len=%02hhX,proto_addr_len=%02hhX,op=%04hX", this->arp->hardware_type.load(), this->arp->protocol_type.load(), this->arp->hwaddr_len, this->arp->paddr_len, this->arp->operation.load()); } else if (this->ipv4) { - ret += string_printf(",IPv4,size=%04hX,src=%08" PRIX32 ",dest=%08" PRIX32, + ret += string_printf( + ",IPv4,size=%04hX,src=%08" PRIX32 ",dest=%08" PRIX32, this->ipv4->size.load(), this->ipv4->src_addr.load(), this->ipv4->dest_addr.load()); if (this->udp) { - ret += string_printf(",UDP,src_port=%04hX,dest_port=%04hX,size=%04hX", + ret += string_printf( + ",UDP,src_port=%04hX,dest_port=%04hX,size=%04hX", this->udp->src_port.load(), this->udp->dest_port.load(), this->udp->size.load()); } else if (this->tcp) { - ret += string_printf(",TCP,src_port=%04hX,dest_port=%04hX,seq=%08" PRIX32 ",ack=%08" PRIX32 ",flags=%04hX(", + ret += string_printf( + ",TCP,src_port=%04hX,dest_port=%04hX,seq=%08" PRIX32 ",ack=%08" PRIX32 ",flags=%04hX(", this->tcp->src_port.load(), this->tcp->dest_port.load(), this->tcp->seq_num.load(), this->tcp->ack_num.load(), this->tcp->flags.load()); if (this->tcp->flags & TCPHeader::Flag::FIN) { ret += "FIN,"; diff --git a/src/IPFrameInfo.hh b/src/IPFrameInfo.hh index c76f3f32..85df9b6d 100644 --- a/src/IPFrameInfo.hh +++ b/src/IPFrameInfo.hh @@ -4,8 +4,6 @@ #include - - struct EthernetHeader { uint8_t dest_mac[6]; uint8_t src_mac[6]; @@ -42,7 +40,7 @@ struct UDPHeader { struct TCPHeader { enum Flag { - NS = 0x0100, + NS = 0x0100, CWR = 0x0080, // congestion window reduced ECE = 0x0040, // ECN capable / congestion experienced URG = 0x0020, // urgent pointer used @@ -63,8 +61,6 @@ struct TCPHeader { be_uint16_t urgent_ptr; } __attribute__((packed)); - - struct FrameInfo { // This is always valid const EthernetHeader* ether; diff --git a/src/IPStackSimulator.cc b/src/IPStackSimulator.cc index c6d62400..565a89fd 100644 --- a/src/IPStackSimulator.cc +++ b/src/IPStackSimulator.cc @@ -1,30 +1,26 @@ #include "IPStackSimulator.hh" -#include -#include -#include +#include #include #include #include -#include +#include +#include +#include -#include #include #include #include +#include -#include "Loggers.hh" -#include "IPFrameInfo.hh" #include "DNSServer.hh" +#include "IPFrameInfo.hh" +#include "Loggers.hh" using namespace std; - - static const size_t DEFAULT_RESEND_PUSH_USECS = 200000; // 200ms - - // Note: these functions exist because seq nums are allowed to wrap around the // 32-bit integer space by design. We have to do the subtraction before the // comparison to allow integer overflow to occur if needed. @@ -45,8 +41,6 @@ static __attribute__((unused)) inline bool seq_num_greater_or_equal(uint32_t a, return (a == b) || seq_num_greater(a, b); } - - string IPStackSimulator::str_for_ipv4_netloc(uint32_t addr, uint16_t port) { be_uint32_t be_addr = addr; char addr_str[INET_ADDRSTRLEN]; @@ -67,14 +61,12 @@ string IPStackSimulator::str_for_tcp_connection(shared_ptr c, fd, key, client_netloc_str.c_str(), server_netloc_str.c_str()); } - - IPStackSimulator::IPStackSimulator( std::shared_ptr base, std::shared_ptr state) - : base(base), - state(state), - pcap_text_log_file(state->ip_stack_debug ? fopen("IPStackSimulator-Log.txt", "wt") : nullptr) { + : base(base), + state(state), + pcap_text_log_file(state->ip_stack_debug ? fopen("IPStackSimulator-Log.txt", "wt") : nullptr) { memset(this->host_mac_address_bytes, 0x90, 6); memset(this->broadcast_mac_address_bytes, 0xFF, 6); } @@ -85,8 +77,6 @@ IPStackSimulator::~IPStackSimulator() { } } - - void IPStackSimulator::listen(const std::string& socket_path) { this->add_socket(::listen(socket_path, 0, SOMAXCONN)); } @@ -102,17 +92,15 @@ void IPStackSimulator::listen(int port) { void IPStackSimulator::add_socket(int fd) { this->listeners.emplace( evconnlistener_new( - this->base.get(), - IPStackSimulator::dispatch_on_listen_accept, - this, - LEV_OPT_REUSEABLE, - 0, - fd), + this->base.get(), + IPStackSimulator::dispatch_on_listen_accept, + this, + LEV_OPT_REUSEABLE, + 0, + fd), evconnlistener_free); } - - uint32_t IPStackSimulator::connect_address_for_remote_address(uint32_t remote_addr) { // Use an address not on the same subnet as the client, so that PSO Plus and // Episode III will think they're talking to a remote network and won't reject @@ -124,41 +112,36 @@ uint32_t IPStackSimulator::connect_address_for_remote_address(uint32_t remote_ad } } - - IPStackSimulator::IPClient::IPClient(struct bufferevent* bev) - : bev(bev, bufferevent_free), ipv4_addr(0) { + : bev(bev, bufferevent_free), + ipv4_addr(0) { memset(this->mac_addr, 0, 6); } - - static void flush_and_free_bufferevent(struct bufferevent* bev) { bufferevent_flush(bev, EV_READ | EV_WRITE, BEV_FINISHED); bufferevent_free(bev); } IPStackSimulator::IPClient::TCPConnection::TCPConnection() - : server_bev(nullptr, flush_and_free_bufferevent), - pending_data(evbuffer_new(), evbuffer_free), - resend_push_event(nullptr, event_free), - awaiting_first_ack(true), - server_addr(0), - server_port(0), - client_port(0), - next_client_seq(0), - acked_server_seq(0), - resend_push_usecs(DEFAULT_RESEND_PUSH_USECS), - next_push_max_frame_size(1024), - max_frame_size(1024), - bytes_received(0), - bytes_sent(0) { } - - + : server_bev(nullptr, flush_and_free_bufferevent), + pending_data(evbuffer_new(), evbuffer_free), + resend_push_event(nullptr, event_free), + awaiting_first_ack(true), + server_addr(0), + server_port(0), + client_port(0), + next_client_seq(0), + acked_server_seq(0), + resend_push_usecs(DEFAULT_RESEND_PUSH_USECS), + next_push_max_frame_size(1024), + max_frame_size(1024), + bytes_received(0), + bytes_sent(0) {} void IPStackSimulator::dispatch_on_listen_accept( struct evconnlistener* listener, evutil_socket_t fd, - struct sockaddr *address, int socklen, void* ctx) { + struct sockaddr* address, int socklen, void* ctx) { reinterpret_cast(ctx)->on_listen_accept( listener, fd, address, socklen); } @@ -168,7 +151,7 @@ void IPStackSimulator::on_listen_accept(struct evconnlistener* listener, int listen_fd = evconnlistener_get_fd(listener); ip_stack_simulator_log.info("Virtual network fd %d connected via fd %d", fd, listen_fd); - struct bufferevent *bev = bufferevent_socket_new(this->base.get(), fd, + struct bufferevent* bev = bufferevent_socket_new(this->base.get(), fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); shared_ptr c(new IPClient(bev)); c->sim = this; @@ -191,8 +174,6 @@ void IPStackSimulator::on_listen_error(struct evconnlistener* listener) { event_base_loopexit(this->base.get(), nullptr); } - - void IPStackSimulator::dispatch_on_client_input( struct bufferevent* bev, void* ctx) { reinterpret_cast(ctx)->on_client_input(bev); @@ -250,8 +231,6 @@ void IPStackSimulator::on_client_error(struct bufferevent* bev, } } - - void IPStackSimulator::on_client_frame( shared_ptr c, const string& frame) { if (ip_stack_simulator_log.info("Virtual network sent frame")) { @@ -310,8 +289,6 @@ void IPStackSimulator::on_client_frame( } } - - void IPStackSimulator::on_client_arp_frame( shared_ptr c, const FrameInfo& fi) { if (fi.arp->hwaddr_len != 6 || @@ -330,7 +307,7 @@ void IPStackSimulator::on_client_arp_frame( } if (c->ipv4_addr == 0) { c->ipv4_addr = *reinterpret_cast( - reinterpret_cast(fi.payload) + 6); + reinterpret_cast(fi.payload) + 6); } EthernetHeader r_ether; @@ -382,8 +359,6 @@ void IPStackSimulator::on_client_arp_frame( } } - - void IPStackSimulator::on_client_udp_frame( shared_ptr c, const FrameInfo& fi) { // We only implement the DNS server here @@ -453,20 +428,18 @@ void IPStackSimulator::on_client_udp_frame( } } - - uint64_t IPStackSimulator::tcp_conn_key_for_connection( const IPClient::TCPConnection& conn) { return (static_cast(conn.server_addr) << 32) | - (static_cast(conn.server_port) << 16) | - static_cast(conn.client_port); + (static_cast(conn.server_port) << 16) | + static_cast(conn.client_port); } uint64_t IPStackSimulator::tcp_conn_key_for_client_frame( const IPv4Header& ipv4, const TCPHeader& tcp) { return (static_cast(ipv4.dest_addr) << 32) | - (static_cast(tcp.dest_port) << 16) | - static_cast(tcp.src_port); + (static_cast(tcp.dest_port) << 16) | + static_cast(tcp.src_port); } uint64_t IPStackSimulator::tcp_conn_key_for_client_frame(const FrameInfo& fi) { @@ -476,14 +449,12 @@ uint64_t IPStackSimulator::tcp_conn_key_for_client_frame(const FrameInfo& fi) { return IPStackSimulator::tcp_conn_key_for_client_frame(*fi.ipv4, *fi.tcp); } - void IPStackSimulator::on_client_tcp_frame( shared_ptr c, const FrameInfo& fi) { ip_stack_simulator_log.info("Virtual network sent TCP frame (seq=%08" PRIX32 ", ack=%08" PRIX32 ")", fi.tcp->seq_num.load(), fi.tcp->ack_num.load()); - if (fi.tcp->flags & (TCPHeader::Flag::NS | TCPHeader::Flag::CWR | - TCPHeader::Flag::ECE | TCPHeader::Flag::URG)) { + if (fi.tcp->flags & (TCPHeader::Flag::NS | TCPHeader::Flag::CWR | TCPHeader::Flag::ECE | TCPHeader::Flag::URG)) { throw runtime_error("unsupported flag in TCP packet"); } @@ -536,7 +507,6 @@ void IPStackSimulator::on_client_tcp_frame( } } - uint64_t key = this->tcp_conn_key_for_client_frame(fi); auto emplace_ret = c->tcp_connections.emplace(key, IPClient::TCPConnection()); auto& conn = emplace_ret.first->second; @@ -645,17 +615,18 @@ void IPStackSimulator::on_client_tcp_frame( c->tcp_connections.erase(key); conn_valid = false; - // Note: The PSH flag isn't required to be set on all packets that contain - // data. The PSH flag just means "tell the application that data is - // available", so some senders only set the PSH flag on the last frame of a - // large segment of data, since the application wouldn't be able to process - // the segment until all of it is available. newserv can handle incomplete - // commands, so we just ignore the PSH flag and forward any data to the - // server immediately. + // Note: The PSH flag isn't required to be set on all packets that contain + // data. The PSH flag just means "tell the application that data is + // available", so some senders only set the PSH flag on the last frame of a + // large segment of data, since the application wouldn't be able to process + // the segment until all of it is available. newserv can handle incomplete + // commands, so we just ignore the PSH flag and forward any data to the + // server immediately. } else if (fi.payload_size != 0) { string conn_str = ip_stack_simulator_log.should_log(LogLevel::WARNING) - ? this->str_for_tcp_connection(c, *conn) : ""; + ? this->str_for_tcp_connection(c, *conn) + : ""; size_t payload_skip_bytes; if (fi.tcp->seq_num == conn->next_client_seq) { @@ -939,8 +910,6 @@ void IPStackSimulator::on_server_error( } } - - void IPStackSimulator::log_frame(const string& data) const { if (this->pcap_text_log_file) { print_data(this->pcap_text_log_file, data, 0, nullptr, diff --git a/src/IPStackSimulator.hh b/src/IPStackSimulator.hh index 5dcc03fd..4ff17df6 100644 --- a/src/IPStackSimulator.hh +++ b/src/IPStackSimulator.hh @@ -1,18 +1,16 @@ -#include #include +#include #include -#include -#include #include +#include +#include #include "IPFrameInfo.hh" -#include "Server.hh" #include "ProxyServer.hh" +#include "Server.hh" #include "ServerState.hh" - - class IPStackSimulator { public: IPStackSimulator( @@ -31,10 +29,10 @@ private: std::shared_ptr base; std::shared_ptr state; - using unique_listener = std::unique_ptr; - using unique_bufferevent = std::unique_ptr; - using unique_evbuffer = std::unique_ptr; - using unique_event = std::unique_ptr; + using unique_listener = std::unique_ptr; + using unique_bufferevent = std::unique_ptr; + using unique_evbuffer = std::unique_ptr; + using unique_event = std::unique_ptr; struct IPClient { IPStackSimulator* sim; @@ -93,19 +91,19 @@ private: static std::string str_for_ipv4_netloc(uint32_t addr, uint16_t port); static std::string str_for_tcp_connection(std::shared_ptr c, - const IPClient::TCPConnection& conn); + const IPClient::TCPConnection& conn); static void dispatch_on_listen_accept(struct evconnlistener* listener, - evutil_socket_t fd, struct sockaddr *address, int socklen, void* ctx); + evutil_socket_t fd, struct sockaddr* address, int socklen, void* ctx); void on_listen_accept(struct evconnlistener* listener, evutil_socket_t fd, - struct sockaddr *address, int socklen); + struct sockaddr* address, int socklen); static void dispatch_on_listen_error(struct evconnlistener* listener, void* ctx); void on_listen_error(struct evconnlistener* listener); static void dispatch_on_client_input(struct bufferevent* bev, void* ctx); void on_client_input(struct bufferevent* bev); static void dispatch_on_client_error(struct bufferevent* bev, short events, - void* ctx); + void* ctx); void on_client_error(struct bufferevent* bev, short events); void on_client_frame(std::shared_ptr c, const std::string& frame); @@ -114,13 +112,13 @@ private: void on_client_tcp_frame(std::shared_ptr c, const FrameInfo& fi); static void dispatch_on_resend_push(evutil_socket_t fd, short events, - void* ctx); + void* ctx); void on_resend_push(std::shared_ptr c, IPClient::TCPConnection& conn); static void dispatch_on_server_input(struct bufferevent* bev, void* ctx); void on_server_input(std::shared_ptr c, IPClient::TCPConnection& conn); static void dispatch_on_server_error(struct bufferevent* bev, short events, - void* ctx); + void* ctx); void on_server_error(std::shared_ptr c, IPClient::TCPConnection& conn, short events); void send_pending_push_frame( diff --git a/src/ItemCreator.cc b/src/ItemCreator.cc index e801b158..a33f7bf0 100644 --- a/src/ItemCreator.cc +++ b/src/ItemCreator.cc @@ -5,8 +5,6 @@ using namespace std; - - ItemCreator::ItemCreator( shared_ptr common_item_set, shared_ptr rare_item_set, @@ -20,28 +18,26 @@ ItemCreator::ItemCreator( uint8_t section_id, uint32_t random_seed, shared_ptr restrictions) - : log("[ItemCreator] "), - episode(episode), - mode(mode), - difficulty(difficulty), - section_id(section_id), - common_item_set(common_item_set), - rare_item_set(rare_item_set), - armor_random_set(armor_random_set), - tool_random_set(tool_random_set), - weapon_random_set(weapon_random_set), - item_parameter_table(item_parameter_table), - pt(&this->common_item_set->get_table( - this->episode, this->mode, this->difficulty, this->section_id)), - rt(&this->rare_item_set->get_table( - this->episode, this->mode, this->difficulty, this->section_id)), - restrictions(restrictions), - random_crypt(random_seed) { + : log("[ItemCreator] "), + episode(episode), + mode(mode), + difficulty(difficulty), + section_id(section_id), + common_item_set(common_item_set), + rare_item_set(rare_item_set), + armor_random_set(armor_random_set), + tool_random_set(tool_random_set), + weapon_random_set(weapon_random_set), + item_parameter_table(item_parameter_table), + pt(&this->common_item_set->get_table( + this->episode, this->mode, this->difficulty, this->section_id)), + rt(&this->rare_item_set->get_table( + this->episode, this->mode, this->difficulty, this->section_id)), + restrictions(restrictions), + random_crypt(random_seed) { print_data(stderr, this->pt, sizeof(*this->pt)); } - - bool ItemCreator::are_rare_drops_allowed() const { // Note: The client has an additional check here, which appears to be a subtle // anti-cheating measure. There is a flag on the client, initially zero, which @@ -74,23 +70,23 @@ uint8_t ItemCreator::normalize_area_number(uint8_t area) const { throw logic_error("this should be impossible"); case Episode::EP2: { static const vector area_subs = { - 0x01, // 13 (VR Temple Alpha) - 0x02, // 14 (VR Temple Beta) - 0x03, // 15 (VR Spaceship Alpha) - 0x04, // 16 (VR Spaceship Beta) - 0x08, // 17 (Central Control Area) - 0x05, // 18 (Jungle North) - 0x06, // 19 (Jungle South) - 0x07, // 1A (Mountain) - 0x08, // 1B (Seaside) - 0x09, // 1C (Seabed Upper) - 0x0A, // 1D (Seabed Lower) - 0x09, // 1E (Gal Gryphon) - 0x0A, // 1F (Olga Flow) - 0x03, // 20 (Barba Ray) - 0x05, // 21 (Gol Dragon) - 0x08, // 22 (Seaside Night) - 0x0A, // 23 (Tower) + 0x01, // 13 (VR Temple Alpha) + 0x02, // 14 (VR Temple Beta) + 0x03, // 15 (VR Spaceship Alpha) + 0x04, // 16 (VR Spaceship Beta) + 0x08, // 17 (Central Control Area) + 0x05, // 18 (Jungle North) + 0x06, // 19 (Jungle South) + 0x07, // 1A (Mountain) + 0x08, // 1B (Seaside) + 0x09, // 1C (Seabed Upper) + 0x0A, // 1D (Seabed Lower) + 0x09, // 1E (Gal Gryphon) + 0x0A, // 1F (Olga Flow) + 0x03, // 20 (Barba Ray) + 0x05, // 21 (Gol Dragon) + 0x08, // 22 (Seaside Night) + 0x0A, // 23 (Tower) }; if ((area >= 0x13) && (area < 0x24)) { return area_subs.at(area - 0x13); @@ -109,8 +105,6 @@ uint8_t ItemCreator::normalize_area_number(uint8_t area) const { } } - - ItemData ItemCreator::on_box_item_drop(uint8_t area) { return this->on_box_item_drop_with_norm_area(normalize_area_number(area) - 1); } @@ -174,8 +168,10 @@ ItemData ItemCreator::on_monster_item_drop_with_norm_area( ItemData item = this->check_rare_spec_and_create_rare_enemy_item(enemy_type); if (item.empty()) { - uint32_t item_class_determinant = this->should_allow_meseta_drops() - ? this->rand_int(3) : (this->rand_int(2) + 1); + uint32_t item_class_determinant = + this->should_allow_meseta_drops() + ? this->rand_int(3) + : (this->rand_int(2) + 1); uint32_t item_class; switch (item_class_determinant) { @@ -193,7 +189,7 @@ ItemData ItemCreator::on_monster_item_drop_with_norm_area( } this->log.info("Rare drop not chosen; item class determinant is %" PRIu32 "; item class is %" PRIu32, - item_class_determinant, item_class); + item_class_determinant, item_class); switch (item_class) { case 0: // Weapon @@ -214,7 +210,8 @@ ItemData ItemCreator::on_monster_item_drop_with_norm_area( case 5: // Meseta item.data1[0] = 0x04; item.data2d = this->choose_meseta_amount( - this->pt->enemy_meseta_ranges, enemy_type) & 0xFFFF; + this->pt->enemy_meseta_ranges, enemy_type) & + 0xFFFF; break; default: return item; @@ -246,8 +243,6 @@ ItemData ItemCreator::check_rare_specs_and_create_rare_box_item( return item; } - - uint32_t ItemCreator::rand_int(uint64_t max) { return this->random_crypt.next() % max; } @@ -348,7 +343,7 @@ void ItemCreator::generate_rare_weapon_bonuses( // item.data1[z + 7] by 5 and multiplies it by 5 again if bonus_type is 5 // (Hit). Why this is done is unclear, because item.data1[z + 7] must // already be a multiple of 5. - } + } this->deduplicate_weapon_bonuses(item); } @@ -403,8 +398,6 @@ void ItemCreator::set_item_unidentified_flag_if_challenge(ItemData& item) const } } - - void ItemCreator::set_tool_item_amount_to_1(ItemData& item) const { if (item.data1[0] == 0x03) { item.set_tool_item_amount(1); @@ -418,8 +411,6 @@ void ItemCreator::clear_tool_item_if_invalid(ItemData& item) { } } - - void ItemCreator::clear_item_if_restricted(ItemData& item) const { if (this->item_parameter_table->is_item_rare(item) && !this->are_rare_drops_allowed()) { this->log.info("Restricted: item is rare, but rares not allowed"); @@ -432,9 +423,8 @@ void ItemCreator::clear_item_if_restricted(ItemData& item) const { // Note: PSO GC doesn't check for 0x61 or 0x62 here since those items // (HP/Resurrection and TP/Resurrection) only exist on BB. if (item.data1[0] == 1) { - if ((item.data1[1] == 3) && ( - ((item.data1[2] >= 0x33) && (item.data1[2] <= 0x38)) || - (item.data1[2] == 0x61) || (item.data1[2] == 0x62))) { + if ((item.data1[1] == 3) && (((item.data1[2] >= 0x33) && (item.data1[2] <= 0x38)) || + (item.data1[2] == 0x61) || (item.data1[2] == 0x62))) { this->log.info("Restricted: restore items not allowed in Challenge mode"); item.clear(); } @@ -486,7 +476,7 @@ void ItemCreator::clear_item_if_restricted(ItemData& item) const { break; case Restrictions::TechDiskMode::LIMIT_LEVEL: this->log.info("Restricted: tech disk level limited to %hhu", - static_cast(this->restrictions->max_tech_disk_level + 1)); + static_cast(this->restrictions->max_tech_disk_level + 1)); if (this->restrictions->max_tech_disk_level == 0) { item.data1[2] = 0; } else { @@ -513,8 +503,6 @@ void ItemCreator::clear_item_if_restricted(ItemData& item) const { } } - - void ItemCreator::generate_common_item_variances( uint32_t norm_area, ItemData& item) { switch (item.data1[0]) { @@ -543,7 +531,8 @@ void ItemCreator::generate_common_item_variances( break; case 4: item.data2d = this->choose_meseta_amount( - this->pt->box_meseta_ranges, norm_area) & 0xFFFF; + this->pt->box_meseta_ranges, norm_area) & + 0xFFFF; break; default: // Note: The original code does the following here: @@ -590,8 +579,6 @@ void ItemCreator::generate_common_armor_slot_count(ItemData& item) { this->pt->armor_slot_count_prob_table); } - - void ItemCreator::generate_common_tool_variances( uint32_t area_norm, ItemData& item) { item.clear(); @@ -633,8 +620,6 @@ void ItemCreator::generate_common_tool_type( item.data1[2] = data.second; } - - void ItemCreator::generate_common_mag_variances(ItemData& item) const { if (item.data1[0] == 0x02) { item.data1[1] = 0x00; @@ -642,8 +627,6 @@ void ItemCreator::generate_common_mag_variances(ItemData& item) const { } } - - void ItemCreator::generate_common_weapon_variances( uint8_t area_norm, ItemData& item) { item.clear(); @@ -730,8 +713,6 @@ uint8_t ItemCreator::choose_weapon_special(uint8_t det) { return 0; } - - void ItemCreator::generate_unit_weights_tables() { // Note: This part of the function was originally in a different function, // since it had another callsite. Unlike the original code, we generate these @@ -817,11 +798,9 @@ void ItemCreator::generate_common_unit_variances(uint8_t det, ItemData& item) { } } - - // Returns a weighted random result, indicating the chosen position in the // weighted table. -// +// // For example, an input table of 40 40 40 40 would be equally likely to return // 0, 1, 2, or 3. An input table of 40 40 80 would return 2 50% of the time, and // 0 or 1 each 25% of the time. @@ -857,11 +836,9 @@ template IntT ItemCreator::get_rand_from_weighted_tables_2d_vertical( const parray, Y>& tables, size_t offset) { return ItemCreator::get_rand_from_weighted_tables(tables[0].data(), - offset, Y, X); + offset, Y, X); } - - // Note: There are clearly better ways of doing this, but this implementation // closely follows what the original code in the client does. template @@ -869,7 +846,7 @@ struct ProbabilityTable { ItemT items[MaxCount]; size_t count; - ProbabilityTable() : count(0) { } + ProbabilityTable() : count(0) {} void push(ItemT item) { if (this->count == MaxCount) { @@ -999,7 +976,7 @@ void ItemCreator::generate_armor_shop_armors( } pt.shuffle(this->random_crypt); - for (size_t items_generated = 0; items_generated < num_items; ) { + for (size_t items_generated = 0; items_generated < num_items;) { ItemData item; item.data1[0] = 1; item.data1[1] = 1; @@ -1044,7 +1021,7 @@ void ItemCreator::generate_armor_shop_shields( } pt.shuffle(this->random_crypt); - for (size_t items_generated = 0; items_generated < num_items; ) { + for (size_t items_generated = 0; items_generated < num_items;) { ItemData item; item.data1[0] = 1; item.data1[1] = 2; @@ -1072,7 +1049,7 @@ void ItemCreator::generate_armor_shop_units( return; // num_items = 0 } else if (player_level < 26) { num_items = 3; - } else if (player_level < 43) { + } else if (player_level < 43) { num_items = 5; } else { num_items = 6; @@ -1088,7 +1065,7 @@ void ItemCreator::generate_armor_shop_units( } pt.shuffle(this->random_crypt); - for (size_t items_generated = 0; items_generated < num_items; ) { + for (size_t items_generated = 0; items_generated < num_items;) { ItemData item; item.data1[0] = 1; item.data1[1] = 3; @@ -1100,8 +1077,6 @@ void ItemCreator::generate_armor_shop_units( } } - - vector ItemCreator::generate_tool_shop_contents(size_t player_level) { vector shop; this->generate_common_tool_shop_recovery_items(shop, player_level); @@ -1126,22 +1101,22 @@ size_t ItemCreator::get_table_index_for_tool_shop(size_t player_level) { } static const vector> tool_item_defs({ - {0x00, 0x00}, - {0x00, 0x01}, - {0x00, 0x02}, - {0x01, 0x00}, - {0x01, 0x01}, - {0x01, 0x02}, - {0x06, 0x00}, - {0x06, 0x01}, - {0x03, 0x00}, - {0x04, 0x00}, - {0x05, 0x00}, - {0x07, 0x00}, - {0x08, 0x00}, - {0x09, 0x00}, - {0x0A, 0x00}, - {0xFF, 0xFF}, + {0x00, 0x00}, + {0x00, 0x01}, + {0x00, 0x02}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x01, 0x02}, + {0x06, 0x00}, + {0x06, 0x01}, + {0x03, 0x00}, + {0x04, 0x00}, + {0x05, 0x00}, + {0x07, 0x00}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0A, 0x00}, + {0xFF, 0xFF}, }); void ItemCreator::generate_common_tool_shop_recovery_items( @@ -1288,8 +1263,6 @@ void ItemCreator::choose_tech_disk_level_for_tool_shop( } } - - vector ItemCreator::generate_weapon_shop_contents(size_t player_level) { size_t num_items; if (player_level < 11) { @@ -1350,8 +1323,16 @@ vector ItemCreator::generate_weapon_shop_contents(size_t player_level) uint8_t which = pt.pop(); if (which == 0x39) { static const vector> defs({ - {0x28, 0x00}, {0x2A, 0x00}, {0x2B, 0x00}, {0x35, 0x00}, {0x52, 0x00}, - {0x48, 0x00}, {0x64, 0x00}, {0x59, 0x00}, {0x8A, 0x00}, {0x99, 0x00}, + {0x28, 0x00}, + {0x2A, 0x00}, + {0x2B, 0x00}, + {0x35, 0x00}, + {0x52, 0x00}, + {0x48, 0x00}, + {0x64, 0x00}, + {0x59, 0x00}, + {0x8A, 0x00}, + {0x99, 0x00}, }); const auto& def = defs.at(this->section_id); item.data1[0] = 0; @@ -1360,8 +1341,16 @@ vector ItemCreator::generate_weapon_shop_contents(size_t player_level) } else if (which == 0x3A) { static const vector> defs({ - {0x99, 0x00}, {0x64, 0x00}, {0x8A, 0x00}, {0x28, 0x00}, {0x59, 0x00}, - {0x2B, 0x00}, {0x52, 0x00}, {0x2A, 0x00}, {0x48, 0x00}, {0x35, 0x00}, + {0x99, 0x00}, + {0x64, 0x00}, + {0x8A, 0x00}, + {0x28, 0x00}, + {0x59, 0x00}, + {0x2B, 0x00}, + {0x52, 0x00}, + {0x2A, 0x00}, + {0x48, 0x00}, + {0x35, 0x00}, }); const auto& def = defs.at(this->section_id); item.data1[0] = 0; @@ -1370,21 +1359,78 @@ vector ItemCreator::generate_weapon_shop_contents(size_t player_level) } else { static const vector> defs({ - {0x01, 0x00}, {0x01, 0x01}, {0x01, 0x02}, {0x01, 0x03}, {0x01, 0x04}, - {0x03, 0x00}, {0x03, 0x01}, {0x03, 0x02}, {0x03, 0x03}, {0x03, 0x04}, - {0x02, 0x00}, {0x02, 0x01}, {0x02, 0x02}, {0x02, 0x03}, {0x02, 0x04}, - {0x05, 0x00}, {0x05, 0x01}, {0x05, 0x02}, {0x05, 0x03}, {0x05, 0x04}, - {0x04, 0x00}, {0x04, 0x01}, {0x04, 0x02}, {0x04, 0x03}, {0x04, 0x04}, - {0x06, 0x00}, {0x06, 0x01}, {0x06, 0x02}, {0x06, 0x03}, {0x06, 0x04}, - {0x07, 0x00}, {0x07, 0x01}, {0x07, 0x02}, {0x07, 0x03}, {0x07, 0x04}, - {0x08, 0x00}, {0x08, 0x01}, {0x08, 0x02}, {0x08, 0x03}, {0x08, 0x04}, - {0x09, 0x00}, {0x09, 0x01}, {0x09, 0x02}, {0x09, 0x03}, {0x09, 0x04}, - {0x0A, 0x00}, {0x0A, 0x01}, {0x0A, 0x02}, {0x0A, 0x03}, {0x0B, 0x00}, - {0x0B, 0x01}, {0x0B, 0x02}, {0x0B, 0x03}, {0x0C, 0x00}, {0x0C, 0x01}, - {0x0C, 0x02}, {0x0C, 0x03}, {0xFF, 0xFF}, {0xFF, 0xFF}, {0x01, 0x05}, - {0x02, 0x05}, {0x06, 0x05}, {0x08, 0x05}, {0x0A, 0x04}, {0x0C, 0x04}, - {0x0B, 0x04}, {0x01, 0x06}, {0x03, 0x05}, {0x07, 0x05}, {0x0A, 0x05}, - {0x0C, 0x05}, {0x0B, 0x05}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x01, 0x02}, + {0x01, 0x03}, + {0x01, 0x04}, + {0x03, 0x00}, + {0x03, 0x01}, + {0x03, 0x02}, + {0x03, 0x03}, + {0x03, 0x04}, + {0x02, 0x00}, + {0x02, 0x01}, + {0x02, 0x02}, + {0x02, 0x03}, + {0x02, 0x04}, + {0x05, 0x00}, + {0x05, 0x01}, + {0x05, 0x02}, + {0x05, 0x03}, + {0x05, 0x04}, + {0x04, 0x00}, + {0x04, 0x01}, + {0x04, 0x02}, + {0x04, 0x03}, + {0x04, 0x04}, + {0x06, 0x00}, + {0x06, 0x01}, + {0x06, 0x02}, + {0x06, 0x03}, + {0x06, 0x04}, + {0x07, 0x00}, + {0x07, 0x01}, + {0x07, 0x02}, + {0x07, 0x03}, + {0x07, 0x04}, + {0x08, 0x00}, + {0x08, 0x01}, + {0x08, 0x02}, + {0x08, 0x03}, + {0x08, 0x04}, + {0x09, 0x00}, + {0x09, 0x01}, + {0x09, 0x02}, + {0x09, 0x03}, + {0x09, 0x04}, + {0x0A, 0x00}, + {0x0A, 0x01}, + {0x0A, 0x02}, + {0x0A, 0x03}, + {0x0B, 0x00}, + {0x0B, 0x01}, + {0x0B, 0x02}, + {0x0B, 0x03}, + {0x0C, 0x00}, + {0x0C, 0x01}, + {0x0C, 0x02}, + {0x0C, 0x03}, + {0xFF, 0xFF}, + {0xFF, 0xFF}, + {0x01, 0x05}, + {0x02, 0x05}, + {0x06, 0x05}, + {0x08, 0x05}, + {0x0A, 0x04}, + {0x0C, 0x04}, + {0x0B, 0x04}, + {0x01, 0x06}, + {0x03, 0x05}, + {0x07, 0x05}, + {0x0A, 0x05}, + {0x0C, 0x05}, + {0x0B, 0x05}, }); const auto& def = defs.at(which); item.data1[0] = 0; @@ -1431,8 +1477,8 @@ void ItemCreator::generate_weapon_shop_item_grind( uint8_t favored_weapon = favored_weapon_by_section_id.at(this->section_id); bool is_favored = (favored_weapon != 0xFF) && (item.data1[1] == favored_weapon); const auto* range = is_favored - ? this->weapon_random_set->get_favored_grind_range(table_index) - : this->weapon_random_set->get_standard_grind_range(table_index); + ? this->weapon_random_set->get_favored_grind_range(table_index) + : this->weapon_random_set->get_standard_grind_range(table_index); const auto& weapon_def = this->item_parameter_table->get_weapon( item.data1[1], item.data1[2]); @@ -1491,8 +1537,26 @@ void ItemCreator::generate_weapon_shop_item_special( } static const array bonus_values = { - -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, - 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, + -50, + -45, + -40, + -35, + -30, + -25, + -20, + -15, + -10, + -5, + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50, }; void ItemCreator::generate_weapon_shop_item_bonus1( diff --git a/src/ItemCreator.hh b/src/ItemCreator.hh index 55eacbc8..0c0d1c15 100644 --- a/src/ItemCreator.hh +++ b/src/ItemCreator.hh @@ -3,12 +3,10 @@ #include #include "CommonItemSet.hh" -#include "RareItemSet.hh" #include "ItemParameterTable.hh" -#include "StaticGameData.hh" #include "PSOEncryption.hh" - - +#include "RareItemSet.hh" +#include "StaticGameData.hh" struct ItemDropSub { uint8_t override_area; @@ -137,7 +135,7 @@ private: void generate_common_mag_variances(ItemData& item) const; void generate_common_weapon_variances(uint8_t area_norm, ItemData& item); void generate_common_weapon_grind(ItemData& item, - uint8_t offset_within_subtype_range); + uint8_t offset_within_subtype_range); void generate_common_weapon_bonuses(ItemData& item, uint8_t area_norm); void generate_common_weapon_special(ItemData& item, uint8_t area_norm); uint8_t choose_weapon_special(uint8_t det); diff --git a/src/ItemData.cc b/src/ItemData.cc index e78f8b7b..34957af3 100644 --- a/src/ItemData.cc +++ b/src/ItemData.cc @@ -4,8 +4,6 @@ using namespace std; - - ItemData::ItemData() { this->clear(); } @@ -25,10 +23,10 @@ ItemData& ItemData::operator=(const ItemData& other) { bool ItemData::operator==(const ItemData& other) const { return ((this->data1d[0] == other.data1d[0]) && - (this->data1d[1] == other.data1d[1]) && - (this->data1d[2] == other.data1d[2]) && - (this->id == other.id) && - (this->data2d == other.data2d)); + (this->data1d[1] == other.data1d[1]) && + (this->data1d[2] == other.data1d[2]) && + (this->id == other.id) && + (this->data2d == other.data2d)); } bool ItemData::operator!=(const ItemData& other) const { @@ -43,9 +41,9 @@ void ItemData::clear() { bool ItemData::empty() const { return (this->data1d[0] == 0) && - (this->data1d[1] == 0) && - (this->data1d[2] == 0) && - (this->data2d == 0); + (this->data1d[1] == 0) && + (this->data1d[2] == 0) && + (this->data2d == 0); } uint32_t ItemData::primary_identifier() const { @@ -78,8 +76,6 @@ size_t ItemData::max_stack_size() const { return max_stack_size_for_item(this->data1[0], this->data1[1]); } - - void ItemData::assign_mag_stats(const ItemMagStats& mag) { // this->data1[0] and [1] unchanged this->data1[2] = mag.level(); @@ -102,8 +98,6 @@ void ItemData::clear_mag_stats() { } } - - void ItemData::set_sealed_item_kill_count(uint16_t v) { this->data1[10] = (v >> 8) | 0x80; this->data1[11] = v; @@ -145,8 +139,6 @@ void ItemData::set_unit_bonus(int16_t bonus) { this->data1w[3] = bonus; } - - bool ItemData::has_bonuses() const { switch (this->data1[0]) { case 0: @@ -165,7 +157,7 @@ bool ItemData::has_bonuses() const { [[fallthrough]]; case 2: return ((this->get_armor_or_shield_defense_bonus() > 0) || - (this->get_common_armor_evasion_bonus() > 0)); + (this->get_common_armor_evasion_bonus() > 0)); case 3: return (this->get_unit_bonus() > 0); default: @@ -197,8 +189,6 @@ bool ItemData::is_s_rank_weapon() const { return false; } - - bool ItemData::compare_for_sort(const ItemData& a, const ItemData& b) { for (size_t z = 0; z < 12; z++) { if (a.data1[z] < b.data1[z]) { @@ -217,67 +207,65 @@ bool ItemData::compare_for_sort(const ItemData& a, const ItemData& b) { return false; } - - const unordered_map name_for_weapon_special({ - {0x00, nullptr}, - {0x01, "Draw"}, - {0x02, "Drain"}, - {0x03, "Fill"}, - {0x04, "Gush"}, - {0x05, "Heart"}, - {0x06, "Mind"}, - {0x07, "Soul"}, - {0x08, "Geist"}, - {0x09, "Master\'s"}, - {0x0A, "Lord\'s"}, - {0x0B, "King\'s"}, - {0x0C, "Charge"}, - {0x0D, "Spirit"}, - {0x0E, "Berserk"}, - {0x0F, "Ice"}, - {0x10, "Frost"}, - {0x11, "Freeze"}, - {0x12, "Blizzard"}, - {0x13, "Bind"}, - {0x14, "Hold"}, - {0x15, "Seize"}, - {0x16, "Arrest"}, - {0x17, "Heat"}, - {0x18, "Fire"}, - {0x19, "Flame"}, - {0x1A, "Burning"}, - {0x1B, "Shock"}, - {0x1C, "Thunder"}, - {0x1D, "Storm"}, - {0x1E, "Tempest"}, - {0x1F, "Dim"}, - {0x20, "Shadow"}, - {0x21, "Dark"}, - {0x22, "Hell"}, - {0x23, "Panic"}, - {0x24, "Riot"}, - {0x25, "Havoc"}, - {0x26, "Chaos"}, - {0x27, "Devil\'s"}, - {0x28, "Demon\'s"}, + {0x00, nullptr}, + {0x01, "Draw"}, + {0x02, "Drain"}, + {0x03, "Fill"}, + {0x04, "Gush"}, + {0x05, "Heart"}, + {0x06, "Mind"}, + {0x07, "Soul"}, + {0x08, "Geist"}, + {0x09, "Master\'s"}, + {0x0A, "Lord\'s"}, + {0x0B, "King\'s"}, + {0x0C, "Charge"}, + {0x0D, "Spirit"}, + {0x0E, "Berserk"}, + {0x0F, "Ice"}, + {0x10, "Frost"}, + {0x11, "Freeze"}, + {0x12, "Blizzard"}, + {0x13, "Bind"}, + {0x14, "Hold"}, + {0x15, "Seize"}, + {0x16, "Arrest"}, + {0x17, "Heat"}, + {0x18, "Fire"}, + {0x19, "Flame"}, + {0x1A, "Burning"}, + {0x1B, "Shock"}, + {0x1C, "Thunder"}, + {0x1D, "Storm"}, + {0x1E, "Tempest"}, + {0x1F, "Dim"}, + {0x20, "Shadow"}, + {0x21, "Dark"}, + {0x22, "Hell"}, + {0x23, "Panic"}, + {0x24, "Riot"}, + {0x25, "Havoc"}, + {0x26, "Chaos"}, + {0x27, "Devil\'s"}, + {0x28, "Demon\'s"}, }); const unordered_map name_for_s_rank_special({ - {0x01, "Jellen"}, - {0x02, "Zalure"}, - {0x05, "Burning"}, - {0x06, "Tempest"}, - {0x07, "Blizzard"}, - {0x08, "Arrest"}, - {0x09, "Chaos"}, - {0x0A, "Hell"}, - {0x0B, "Spirit"}, - {0x0C, "Berserk"}, - {0x0D, "Demon\'s"}, - {0x0E, "Gush"}, - {0x0F, "Geist"}, - {0x10, "King\'s"}, + {0x01, "Jellen"}, + {0x02, "Zalure"}, + {0x05, "Burning"}, + {0x06, "Tempest"}, + {0x07, "Blizzard"}, + {0x08, "Arrest"}, + {0x09, "Chaos"}, + {0x0A, "Hell"}, + {0x0B, "Spirit"}, + {0x0C, "Berserk"}, + {0x0D, "Demon\'s"}, + {0x0E, "Gush"}, + {0x0F, "Geist"}, + {0x10, "King\'s"}, }); struct ItemNameInfo { @@ -285,974 +273,975 @@ struct ItemNameInfo { bool is_rare; ItemNameInfo(const char* name, bool is_rare = true) - : name(name), is_rare(is_rare) { } + : name(name), + is_rare(is_rare) {} }; const unordered_map name_info_for_primary_identifier({ - // Weapons (00xxxx) - {0x000100, {"Saber", false}}, - {0x000101, {"Brand", false}}, - {0x000102, {"Buster", false}}, - {0x000103, {"Pallasch", false}}, - {0x000104, {"Gladius", false}}, - {0x000105, "DB\'s SABER"}, - {0x000106, "KALADBOLG"}, - {0x000107, "DURANDAL"}, - {0x000108, "GALATINE"}, - {0x000200, {"Sword", false}}, - {0x000201, {"Gigush", false}}, - {0x000202, {"Breaker", false}}, - {0x000203, {"Claymore", false}}, - {0x000204, {"Calibur", false}}, - {0x000205, "FLOWEN\'S SWORD"}, - {0x000206, "LAST SURVIVOR"}, - {0x000207, "DRAGON SLAYER"}, - {0x000300, {"Dagger", false}}, - {0x000301, {"Knife", false}}, - {0x000302, {"Blade", false}}, - {0x000303, {"Edge", false}}, - {0x000304, {"Ripper", false}}, - {0x000305, "BLADE DANCE"}, - {0x000306, "BLOODY ART"}, - {0x000307, "CROSS SCAR"}, - {0x000308, "ZERO DIVIDE"}, - {0x000309, "TWIN KAMUI"}, - {0x000400, {"Partisan", false}}, - {0x000401, {"Halbert", false}}, - {0x000402, {"Glaive", false}}, - {0x000403, {"Berdys", false}}, - {0x000404, {"Gungnir", false}}, - {0x000405, "BRIONAC"}, - {0x000406, "VJAYA"}, - {0x000407, "GAE BOLG"}, - {0x000408, "ASTERON BELT"}, - {0x000500, {"Slicer", false}}, - {0x000501, {"Spinner", false}}, - {0x000502, {"Cutter", false}}, - {0x000503, {"Sawcer", false}}, - {0x000504, {"Diska", false}}, - {0x000505, "SLICER OF ASSASSIN"}, - {0x000506, "DISKA OF LIBERATOR"}, - {0x000507, "DISKA OF BRAVEMAN"}, - {0x000508, "IZMAELA"}, - {0x000600, {"Handgun", false}}, - {0x000601, {"Autogun", false}}, - {0x000602, {"Lockgun", false}}, - {0x000603, {"Railgun", false}}, - {0x000604, {"Raygun", false}}, - {0x000605, "VARISTA"}, - {0x000606, "CUSTOM RAY ver.00"}, - {0x000607, "BRAVACE"}, - {0x000608, "TENSION BLASTER"}, - {0x000700, {"Rifle", false}}, - {0x000701, {"Sniper", false}}, - {0x000702, {"Blaster", false}}, - {0x000703, {"Beam", false}}, - {0x000704, {"Laser", false}}, - {0x000705, "VISK-235W"}, - {0x000706, "WALS-MK2"}, - {0x000707, "JUSTY-23ST"}, - {0x000708, "RIANOV 303SNR"}, - {0x000709, "RIANOV 303SNR-1"}, - {0x00070A, "RIANOV 303SNR-2"}, - {0x00070B, "RIANOV 303SNR-3"}, - {0x00070C, "RIANOV 303SNR-4"}, - {0x00070D, "RIANOV 303SNR-5"}, - {0x000800, {"Mechgun", false}}, - {0x000801, {"Assault", false}}, - {0x000802, {"Repeater", false}}, - {0x000803, {"Gatling", false}}, - {0x000804, {"Vulcan", false}}, - {0x000805, "M&A60 VISE"}, - {0x000806, "H&S25 JUSTICE"}, - {0x000807, "L&K14 COMBAT"}, - {0x000900, {"Shot", false}}, - {0x000901, {"Spread", false}}, - {0x000902, {"Cannon", false}}, - {0x000903, {"Launcher", false}}, - {0x000904, {"Arms", false}}, - {0x000905, "CRUSH BULLET"}, - {0x000906, "METEOR SMASH"}, - {0x000907, "FINAL IMPACT"}, - {0x000A00, {"Cane", false}}, - {0x000A01, {"Stick", false}}, - {0x000A02, {"Mace", false}}, - {0x000A03, {"Club", false}}, - {0x000A04, "CLUB OF LACONIUM"}, - {0x000A05, "MACE OF ADAMAN"}, - {0x000A06, "CLUB OF ZUMIURAN"}, - {0x000A07, "LOLLIPOP"}, - {0x000B00, {"Rod", false}}, - {0x000B01, {"Pole", false}}, - {0x000B02, {"Pillar", false}}, - {0x000B03, {"Striker", false}}, - {0x000B04, "BATTLE VERGE"}, - {0x000B05, "BRAVE HAMMER"}, - {0x000B06, "ALIVE AQHU"}, - {0x000B07, "VALKYRIE"}, - {0x000C00, {"Wand", false}}, - {0x000C01, {"Staff", false}}, - {0x000C02, {"Baton", false}}, - {0x000C03, {"Scepter", false}}, - {0x000C04, "FIRE SCEPTER:AGNI"}, - {0x000C05, "ICE STAFF:DAGON"}, - {0x000C06, "STORM WAND:INDRA"}, - {0x000C07, "EARTH WAND BROWNIE"}, - {0x000D00, "PHOTON CLAW"}, - {0x000D01, "SILENCE CLAW"}, - {0x000D02, "NEI\'S CLAW (REPLICA)"}, - {0x000D03, "PHOENIX CLAW"}, - {0x000E00, "DOUBLE SABER"}, - {0x000E01, "STAG CUTLERY"}, - {0x000E02, "TWIN BRAND"}, - {0x000F00, "BRAVE KNUCKLE"}, - {0x000F01, "ANGRY FIST"}, - {0x000F02, "GOD HAND"}, - {0x000F03, "SONIC KNUCKLE"}, - {0x001000, "OROTIAGITO"}, - {0x001001, "AGITO (AUW 1975)"}, - {0x001002, "AGITO (AUW 1983)"}, - {0x001003, "AGITO (AUW 2001)"}, - {0x001004, "AGITO (AUW 1991)"}, - {0x001005, "AGITO (AUW 1977)"}, - {0x001006, "AGITO (AUW 1980)"}, - {0x001007, "RAIKIRI"}, - {0x001100, "SOUL EATER"}, - {0x001101, "SOUL BANISH"}, - {0x001200, "SPREAD NEEDLE"}, - {0x001300, "HOLY RAY"}, - {0x001400, "INFERNO BAZOOKA"}, - {0x001401, "RAMBLING MAY"}, - {0x001402, "L&K38 COMBAT"}, - {0x001500, "FLAME VISIT"}, - {0x001501, "BURNING VISIT"}, - {0x001600, "AKIKO\'S FRYING PAN"}, - {0x001700, "SORCERER\'S CANE"}, - {0x001800, "S-BEAT\'S BLADE"}, - {0x001900, "P-ARMS\'S BLADE"}, - {0x001A00, "DELSABER\'S BUSTER"}, - {0x001B00, "BRINGER\'S RIFLE"}, - {0x001C00, "EGG BLASTER"}, - {0x001D00, "PSYCHO WAND"}, - {0x001E00, "HEAVEN PUNISHER"}, - {0x001F00, "LAVIS CANNON"}, - {0x002000, "VICTOR AXE"}, - {0x002001, "LACONIUM AXE"}, - {0x002100, "CHAIN SAWD"}, - {0x002200, "CADUCEUS"}, - {0x002201, "MERCURIUS ROD"}, - {0x002300, "STING TIP"}, - {0x002400, "MAGICAL PIECE"}, - {0x002500, "TECHNICAL CROZIER"}, - {0x002600, "SUPPRESSED GUN"}, - {0x002700, "ANCIENT SABER"}, - {0x002800, "HARISEN BATTLE FAN"}, - {0x002900, "YAMIGARASU"}, - {0x002A00, "AKIKO\'S WOK"}, - {0x002B00, "TOY HAMMER"}, - {0x002C00, "ELYSION"}, - {0x002D00, "RED SABER"}, - {0x002E00, "METEOR CUDGEL"}, - {0x002F00, "MONKEY KING BAR"}, - {0x002F01, "BLACK KING BAR"}, - {0x003000, "DOUBLE CANNON"}, - {0x003001, "GIRASOLE"}, - {0x003100, "HUGE BATTLE FAN"}, - {0x003200, "TSUMIKIRI J-SWORD"}, - {0x003300, "SEALED J-SWORD"}, - {0x003400, "RED SWORD"}, - {0x003500, "CRAZY TUNE"}, - {0x003600, "TWIN CHAKRAM"}, - {0x003700, "WOK OF AKIKO\'S SHOP"}, - {0x003800, "LAVIS BLADE"}, - {0x003900, "RED DAGGER"}, - {0x003A00, "MADAM\'S PARASOL"}, - {0x003B00, "MADAM\'S UMBRELLA"}, - {0x003C00, "IMPERIAL PICK"}, - {0x003D00, "BERDYSH"}, - {0x003E00, "RED PARTISAN"}, - {0x003F00, "FLIGHT CUTTER"}, - {0x004000, "FLIGHT FAN"}, - {0x004100, "RED SLICER"}, - {0x004200, "HANDGUN:GULD"}, - {0x004201, "MASTER RAVEN"}, - {0x004300, "HANDGUN:MILLA"}, - {0x004301, "LAST SWAN"}, - {0x004400, "RED HANDGUN"}, - {0x004500, "FROZEN SHOOTER"}, - {0x004501, "SNOW QUEEN"}, - {0x004600, "ANTI ANDROID RIFLE"}, - {0x004700, "ROCKET PUNCH"}, - {0x004800, "SAMBA MARACAS"}, - {0x004900, "TWIN PSYCHOGUN"}, - {0x004A00, "DRILL LAUNCHER"}, - {0x004B00, "GULD MILLA"}, - {0x004B01, "DUAL BIRD"}, - {0x004C00, "RED MECHGUN"}, - {0x004D00, "BELRA CANNON"}, - {0x004E00, "PANZER FAUST"}, - {0x004E01, "IRON FAUST"}, - {0x004F00, "SUMMIT MOON"}, - {0x005000, "WINDMILL"}, - {0x005100, "EVIL CURST"}, - {0x005200, "FLOWER CANE"}, - {0x005300, "HILDEBEAR\'S CANE"}, - {0x005400, "HILDEBLUE\'S CANE"}, - {0x005500, "RABBIT WAND"}, - {0x005600, "PLANTAIN LEAF"}, - {0x005601, "FATSIA"}, - {0x005700, "DEMONIC FORK"}, - {0x005800, "STRIKER OF CHAO"}, - {0x005900, "BROOM"}, - {0x005A00, "PROPHETS OF MOTAV"}, - {0x005B00, "THE SIGH OF A GOD"}, - {0x005C00, "TWINKLE STAR"}, - {0x005D00, "PLANTAIN FAN"}, - {0x005E00, "TWIN BLAZE"}, - {0x005F00, "MARINA\'S BAG"}, - {0x006000, "DRAGON\'S CLAW"}, - {0x006100, "PANTHER\'S CLAW"}, - {0x006200, "S-RED\'S BLADE"}, - {0x006300, "PLANTAIN HUGE FAN"}, - {0x006400, "CHAMELEON SCYTHE"}, - {0x006500, "YASMINKOV 3000R"}, - {0x006600, "ANO RIFLE"}, - {0x006700, "BARANZ LAUNCHER"}, - {0x006800, "BRANCH OF PAKUPAKU"}, - {0x006900, "HEART OF POUMN"}, - {0x006A00, "YASMINKOV 2000H"}, - {0x006B00, "YASMINKOV 7000V"}, - {0x006C00, "YASMINKOV 9000M"}, - {0x006D00, "MASER BEAM"}, - {0x006D01, "POWER MASER"}, - {0x006E00, "GAME MAGAZINE"}, - {0x006F00, "FLOWER BOUQUET"}, - {0x007000, {"S-RANK SABER", true}}, - {0x007100, {"S-RANK SWORD", true}}, - {0x007200, {"S-RANK BLADE", true}}, - {0x007300, {"S-RANK PARTISAN", true}}, - {0x007400, {"S-RANK SLICER", true}}, - {0x007500, {"S-RANK GUN", true}}, - {0x007600, {"S-RANK RIFLE", true}}, - {0x007700, {"S-RANK MECHGUN", true}}, - {0x007800, {"S-RANK SHOT", true}}, - {0x007900, {"S-RANK CANE", true}}, - {0x007A00, {"S-RANK ROD", true}}, - {0x007B00, {"S-RANK WAND", true}}, - {0x007C00, {"S-RANK TWIN", true}}, - {0x007D00, {"S-RANK CLAW", true}}, - {0x007E00, {"S-RANK BAZOOKA", true}}, - {0x007F00, {"S-RANK NEEDLE", true}}, - {0x008000, {"S-RANK SCYTHE", true}}, - {0x008100, {"S-RANK HAMMER", true}}, - {0x008200, {"S-RANK MOON", true}}, - {0x008300, {"S-RANK PSYCHOGUN", true}}, - {0x008400, {"S-RANK PUNCH", true}}, - {0x008500, {"S-RANK WINDMILL", true}}, - {0x008600, {"S-RANK HARISEN", true}}, - {0x008700, {"S-RANK KATANA", true}}, - {0x008800, {"S-RANK J-CUTTER", true}}, - {0x008900, "MUSASHI"}, - {0x008901, "YAMATO"}, - {0x008902, "ASUKA"}, - {0x008903, "SANGE & YASHA"}, - {0x008A00, "SANGE"}, - {0x008A01, "YASHA"}, - {0x008A02, "KAMUI"}, - {0x008B00, "PHOTON LAUNCHER"}, - {0x008B01, "GUILTY LIGHT"}, - {0x008B02, "RED SCORPIO"}, - {0x008B03, "PHONON MASER"}, - {0x008C00, "TALIS"}, - {0x008C01, "MAHU"}, - {0x008C02, "HITOGATA"}, - {0x008C03, "DANCING HITOGATA"}, - {0x008C04, "KUNAI"}, - {0x008D00, "NUG-2000 BAZOOKA"}, - {0x008E00, "S-BERILL\'S HANDS #0"}, - {0x008E01, "S-BERILL\'S HANDS #1"}, - {0x008F00, "FLOWEN\'S SWORD (AUW 3060; GREENILL)"}, - {0x008F01, "FLOWEN\'S SWORD (AUW 3064; SKYLY)"}, - {0x008F02, "FLOWEN\'S SWORD (AUW 3067; BLUEFULL)"}, - {0x008F03, "FLOWEN\'S SWORD (AUW 3073; PURPLENUM)"}, - {0x008F04, "FLOWEN\'S SWORD (AUW 3077; PINKAL)"}, - {0x008F05, "FLOWEN\'S SWORD (AUW 3082; REDRIA)"}, - {0x008F06, "FLOWEN\'S SWORD (AUW 3083; ORAN)"}, - {0x008F07, "FLOWEN\'S SWORD (AUW 3084; YELLOWBOZE)"}, - {0x008F08, "FLOWEN\'S SWORD (AUW 3079; WHITILL)"}, - {0x009000, "DB\'S SWORD (AUW 3062; GREENILL)"}, - {0x009001, "DB\'S SWORD (AUW 3067; SKYLY)"}, - {0x009002, "DB\'S SWORD (AUW 3069; BLUEFULL)"}, - {0x009003, "DB\'S SWORD (AUW 3064; PURPLENUM)"}, - {0x009004, "DB\'S SWORD (AUW 3069; PINKAL)"}, - {0x009005, "DB\'S SWORD (AUW 3073; REDRIA)"}, - {0x009006, "DB\'S SWORD (AUW 3070; ORAN)"}, - {0x009007, "DB\'S SWORD (AUW 3075; YELLOWBOZE)"}, - {0x009008, "DB\'S SWORD (AUW 3077; WHITILL)"}, - {0x009100, "GI GUE BAZOOKA"}, - {0x009200, "GUARDIANNA"}, - {0x009300, "VIRIDIA CARD"}, - {0x009301, "GREENILL CARD"}, - {0x009302, "SKYLY CARD"}, - {0x009303, "BLUEFULL CARD"}, - {0x009304, "PURPLENUM CARD"}, - {0x009305, "PINKAL CARD"}, - {0x009306, "REDRIA CARD"}, - {0x009307, "ORAN CARD"}, - {0x009308, "YELLOWBOZE CARD"}, - {0x009309, "WHITILL CARD"}, - {0x009400, "MORNING GLORY"}, - {0x009500, "PARTISAN OF LIGHTING"}, - {0x009600, "GAL WIND"}, - {0x009700, "ZANBA"}, - {0x009800, "RIKA\'S CLAW"}, - {0x009900, "ANGEL HARP"}, - {0x009A00, "DEMOLITION COMET"}, - {0x009B00, "NEI\'S CLAW"}, - {0x009C00, "RAINBOW BATON"}, - {0x009D00, "DARK FLOW"}, - {0x009E00, "DARK METEOR"}, - {0x009F00, "DARK BRIDGE"}, - {0x00A000, "G-ASSASSIN\'S SABERS"}, - {0x00A100, "RAPPY\'S FAN"}, - {0x00A200, "BOOMA\'S CLAW"}, - {0x00A201, "GOBOOMA\'S CLAW"}, - {0x00A202, "GIGOBOOMA\'S CLAW"}, - {0x00A300, "RUBY BULLET"}, - {0x00A400, "AMORE ROSE"}, - {0x00A500, {"S-RANK SWORDS", true}}, - {0x00A600, {"S-RANK LAUNCHER", true}}, - {0x00A700, {"S-RANK CARD", true}}, - {0x00A800, {"S-RANK KNUCKLE", true}}, - {0x00A900, {"S-RANK AXE", true}}, - {0x00AA00, "SLICER OF FANATIC"}, - {0x00AB00, "LAME D\'ARGENT"}, - {0x00AC00, "EXCALIBUR"}, - {0x00AD03, "RAGE DE FEU"}, - {0x00AE00, "DAISY CHAIN"}, - {0x00AF00, "OPHELIE SEIZE"}, - {0x00B000, "MILLE MARTEAUX"}, - {0x00B100, "LE COGNEUR"}, - {0x00B200, "COMMANDER BLADE"}, - {0x00B300, "VIVIENNE"}, - {0x00B400, "KUSANAGI"}, - {0x00B500, "SACRED DUSTER"}, - {0x00B600, "GUREN"}, - {0x00B700, "SHOUREN"}, - {0x00B800, "JIZAI"}, - {0x00B900, "FLAMBERGE"}, - {0x00BA00, "YUNCHANG"}, - {0x00BB00, "SNAKE SPIRE"}, - {0x00BC00, "FLAPJACK FLAPPER"}, - {0x00BD00, "GETSUGASAN"}, - {0x00BE00, "MAGUWA"}, - {0x00BF00, "HEAVEN STRIKER"}, - {0x00C000, "CANNON ROUGE"}, - {0x00C100, "METEOR ROUGE"}, - {0x00C200, "SOLFERINO"}, - {0x00C300, "CLIO"}, - {0x00C400, "SIREN GLASS HAMMER"}, - {0x00C500, "GLIDE DIVINE"}, - {0x00C600, "SHICHISHITO"}, - {0x00C700, "MURASAME"}, - {0x00C800, "DAYLIGHT SCAR"}, - {0x00C900, "DECALOG"}, - {0x00CA00, "5TH ANNIV. BLADE"}, - {0x00CB00, "PRINCIPAL\'S GIFT PARASOL"}, - {0x00CC00, "AKIKO\'S CLEAVER"}, - {0x00CD00, "TANEGASHIMA"}, - {0x00CE00, "TREE CLIPPERS"}, - {0x00CF00, "NICE SHOT"}, - {0x00D200, "ANO BAZOOKA"}, - {0x00D300, "SYNTHESIZER"}, - {0x00D400, "BAMBOO SPEAR"}, - {0x00D500, "KAN\'EI TSUHO"}, - {0x00D600, "JITTE"}, - {0x00D700, "BUTTERFLY NET"}, - {0x00D800, "SYRINGE"}, - {0x00D900, "BATTLEDORE"}, - {0x00DA00, "RACKET"}, - {0x00DB00, "HAMMER"}, - {0x00DC00, "GREAT BOUQUET"}, - {0x00DD00, "TypeSA/Saber"}, - {0x00DE00, "TypeSL/Saber"}, - {0x00DE01, "TypeSL/Slicer"}, - {0x00DE02, "TypeSL/Claw"}, - {0x00DE03, "TypeSL/Katana"}, - {0x00DF00, "TypeJS/Saber"}, - {0x00DF01, "TypeJS/Slicer"}, - {0x00DF02, "TypeJS/J-Sword"}, - {0x00E000, "TypeSW/Sword"}, - {0x00E001, "TypeSW/Slicer"}, - {0x00E002, "TypeSW/J-Sword"}, - {0x00E100, "TypeRO/Sword"}, - {0x00E101, "TypeRO/Halbert"}, - {0x00E102, "TypeRO/Rod"}, - {0x00E200, "TypeBL/BLADE"}, - {0x00E300, "TypeKN/Blade"}, - {0x00E301, "TypeKN/Claw"}, - {0x00E400, "TypeHA/Halbert"}, - {0x00E401, "TypeHA/Rod"}, - {0x00E500, "TypeDS/D.Saber"}, - {0x00E501, "TypeDS/Rod"}, - {0x00E502, "TypeDS"}, - {0x00E600, "TypeCL/Claw"}, - {0x00E700, "TypeSS/SW"}, - {0x00E800, "TypeGU/Handgun"}, - {0x00E801, "TypeGU/Mechgun"}, - {0x00E900, "TypeRI/Rifle"}, - {0x00EA00, "TypeME/Mechgun"}, - {0x00EB00, "TypeSH/Shot"}, - {0x00EC00, "TypeWA/Wand"}, + // Weapons (00xxxx) + {0x000100, {"Saber", false}}, + {0x000101, {"Brand", false}}, + {0x000102, {"Buster", false}}, + {0x000103, {"Pallasch", false}}, + {0x000104, {"Gladius", false}}, + {0x000105, "DB\'s SABER"}, + {0x000106, "KALADBOLG"}, + {0x000107, "DURANDAL"}, + {0x000108, "GALATINE"}, + {0x000200, {"Sword", false}}, + {0x000201, {"Gigush", false}}, + {0x000202, {"Breaker", false}}, + {0x000203, {"Claymore", false}}, + {0x000204, {"Calibur", false}}, + {0x000205, "FLOWEN\'S SWORD"}, + {0x000206, "LAST SURVIVOR"}, + {0x000207, "DRAGON SLAYER"}, + {0x000300, {"Dagger", false}}, + {0x000301, {"Knife", false}}, + {0x000302, {"Blade", false}}, + {0x000303, {"Edge", false}}, + {0x000304, {"Ripper", false}}, + {0x000305, "BLADE DANCE"}, + {0x000306, "BLOODY ART"}, + {0x000307, "CROSS SCAR"}, + {0x000308, "ZERO DIVIDE"}, + {0x000309, "TWIN KAMUI"}, + {0x000400, {"Partisan", false}}, + {0x000401, {"Halbert", false}}, + {0x000402, {"Glaive", false}}, + {0x000403, {"Berdys", false}}, + {0x000404, {"Gungnir", false}}, + {0x000405, "BRIONAC"}, + {0x000406, "VJAYA"}, + {0x000407, "GAE BOLG"}, + {0x000408, "ASTERON BELT"}, + {0x000500, {"Slicer", false}}, + {0x000501, {"Spinner", false}}, + {0x000502, {"Cutter", false}}, + {0x000503, {"Sawcer", false}}, + {0x000504, {"Diska", false}}, + {0x000505, "SLICER OF ASSASSIN"}, + {0x000506, "DISKA OF LIBERATOR"}, + {0x000507, "DISKA OF BRAVEMAN"}, + {0x000508, "IZMAELA"}, + {0x000600, {"Handgun", false}}, + {0x000601, {"Autogun", false}}, + {0x000602, {"Lockgun", false}}, + {0x000603, {"Railgun", false}}, + {0x000604, {"Raygun", false}}, + {0x000605, "VARISTA"}, + {0x000606, "CUSTOM RAY ver.00"}, + {0x000607, "BRAVACE"}, + {0x000608, "TENSION BLASTER"}, + {0x000700, {"Rifle", false}}, + {0x000701, {"Sniper", false}}, + {0x000702, {"Blaster", false}}, + {0x000703, {"Beam", false}}, + {0x000704, {"Laser", false}}, + {0x000705, "VISK-235W"}, + {0x000706, "WALS-MK2"}, + {0x000707, "JUSTY-23ST"}, + {0x000708, "RIANOV 303SNR"}, + {0x000709, "RIANOV 303SNR-1"}, + {0x00070A, "RIANOV 303SNR-2"}, + {0x00070B, "RIANOV 303SNR-3"}, + {0x00070C, "RIANOV 303SNR-4"}, + {0x00070D, "RIANOV 303SNR-5"}, + {0x000800, {"Mechgun", false}}, + {0x000801, {"Assault", false}}, + {0x000802, {"Repeater", false}}, + {0x000803, {"Gatling", false}}, + {0x000804, {"Vulcan", false}}, + {0x000805, "M&A60 VISE"}, + {0x000806, "H&S25 JUSTICE"}, + {0x000807, "L&K14 COMBAT"}, + {0x000900, {"Shot", false}}, + {0x000901, {"Spread", false}}, + {0x000902, {"Cannon", false}}, + {0x000903, {"Launcher", false}}, + {0x000904, {"Arms", false}}, + {0x000905, "CRUSH BULLET"}, + {0x000906, "METEOR SMASH"}, + {0x000907, "FINAL IMPACT"}, + {0x000A00, {"Cane", false}}, + {0x000A01, {"Stick", false}}, + {0x000A02, {"Mace", false}}, + {0x000A03, {"Club", false}}, + {0x000A04, "CLUB OF LACONIUM"}, + {0x000A05, "MACE OF ADAMAN"}, + {0x000A06, "CLUB OF ZUMIURAN"}, + {0x000A07, "LOLLIPOP"}, + {0x000B00, {"Rod", false}}, + {0x000B01, {"Pole", false}}, + {0x000B02, {"Pillar", false}}, + {0x000B03, {"Striker", false}}, + {0x000B04, "BATTLE VERGE"}, + {0x000B05, "BRAVE HAMMER"}, + {0x000B06, "ALIVE AQHU"}, + {0x000B07, "VALKYRIE"}, + {0x000C00, {"Wand", false}}, + {0x000C01, {"Staff", false}}, + {0x000C02, {"Baton", false}}, + {0x000C03, {"Scepter", false}}, + {0x000C04, "FIRE SCEPTER:AGNI"}, + {0x000C05, "ICE STAFF:DAGON"}, + {0x000C06, "STORM WAND:INDRA"}, + {0x000C07, "EARTH WAND BROWNIE"}, + {0x000D00, "PHOTON CLAW"}, + {0x000D01, "SILENCE CLAW"}, + {0x000D02, "NEI\'S CLAW (REPLICA)"}, + {0x000D03, "PHOENIX CLAW"}, + {0x000E00, "DOUBLE SABER"}, + {0x000E01, "STAG CUTLERY"}, + {0x000E02, "TWIN BRAND"}, + {0x000F00, "BRAVE KNUCKLE"}, + {0x000F01, "ANGRY FIST"}, + {0x000F02, "GOD HAND"}, + {0x000F03, "SONIC KNUCKLE"}, + {0x001000, "OROTIAGITO"}, + {0x001001, "AGITO (AUW 1975)"}, + {0x001002, "AGITO (AUW 1983)"}, + {0x001003, "AGITO (AUW 2001)"}, + {0x001004, "AGITO (AUW 1991)"}, + {0x001005, "AGITO (AUW 1977)"}, + {0x001006, "AGITO (AUW 1980)"}, + {0x001007, "RAIKIRI"}, + {0x001100, "SOUL EATER"}, + {0x001101, "SOUL BANISH"}, + {0x001200, "SPREAD NEEDLE"}, + {0x001300, "HOLY RAY"}, + {0x001400, "INFERNO BAZOOKA"}, + {0x001401, "RAMBLING MAY"}, + {0x001402, "L&K38 COMBAT"}, + {0x001500, "FLAME VISIT"}, + {0x001501, "BURNING VISIT"}, + {0x001600, "AKIKO\'S FRYING PAN"}, + {0x001700, "SORCERER\'S CANE"}, + {0x001800, "S-BEAT\'S BLADE"}, + {0x001900, "P-ARMS\'S BLADE"}, + {0x001A00, "DELSABER\'S BUSTER"}, + {0x001B00, "BRINGER\'S RIFLE"}, + {0x001C00, "EGG BLASTER"}, + {0x001D00, "PSYCHO WAND"}, + {0x001E00, "HEAVEN PUNISHER"}, + {0x001F00, "LAVIS CANNON"}, + {0x002000, "VICTOR AXE"}, + {0x002001, "LACONIUM AXE"}, + {0x002100, "CHAIN SAWD"}, + {0x002200, "CADUCEUS"}, + {0x002201, "MERCURIUS ROD"}, + {0x002300, "STING TIP"}, + {0x002400, "MAGICAL PIECE"}, + {0x002500, "TECHNICAL CROZIER"}, + {0x002600, "SUPPRESSED GUN"}, + {0x002700, "ANCIENT SABER"}, + {0x002800, "HARISEN BATTLE FAN"}, + {0x002900, "YAMIGARASU"}, + {0x002A00, "AKIKO\'S WOK"}, + {0x002B00, "TOY HAMMER"}, + {0x002C00, "ELYSION"}, + {0x002D00, "RED SABER"}, + {0x002E00, "METEOR CUDGEL"}, + {0x002F00, "MONKEY KING BAR"}, + {0x002F01, "BLACK KING BAR"}, + {0x003000, "DOUBLE CANNON"}, + {0x003001, "GIRASOLE"}, + {0x003100, "HUGE BATTLE FAN"}, + {0x003200, "TSUMIKIRI J-SWORD"}, + {0x003300, "SEALED J-SWORD"}, + {0x003400, "RED SWORD"}, + {0x003500, "CRAZY TUNE"}, + {0x003600, "TWIN CHAKRAM"}, + {0x003700, "WOK OF AKIKO\'S SHOP"}, + {0x003800, "LAVIS BLADE"}, + {0x003900, "RED DAGGER"}, + {0x003A00, "MADAM\'S PARASOL"}, + {0x003B00, "MADAM\'S UMBRELLA"}, + {0x003C00, "IMPERIAL PICK"}, + {0x003D00, "BERDYSH"}, + {0x003E00, "RED PARTISAN"}, + {0x003F00, "FLIGHT CUTTER"}, + {0x004000, "FLIGHT FAN"}, + {0x004100, "RED SLICER"}, + {0x004200, "HANDGUN:GULD"}, + {0x004201, "MASTER RAVEN"}, + {0x004300, "HANDGUN:MILLA"}, + {0x004301, "LAST SWAN"}, + {0x004400, "RED HANDGUN"}, + {0x004500, "FROZEN SHOOTER"}, + {0x004501, "SNOW QUEEN"}, + {0x004600, "ANTI ANDROID RIFLE"}, + {0x004700, "ROCKET PUNCH"}, + {0x004800, "SAMBA MARACAS"}, + {0x004900, "TWIN PSYCHOGUN"}, + {0x004A00, "DRILL LAUNCHER"}, + {0x004B00, "GULD MILLA"}, + {0x004B01, "DUAL BIRD"}, + {0x004C00, "RED MECHGUN"}, + {0x004D00, "BELRA CANNON"}, + {0x004E00, "PANZER FAUST"}, + {0x004E01, "IRON FAUST"}, + {0x004F00, "SUMMIT MOON"}, + {0x005000, "WINDMILL"}, + {0x005100, "EVIL CURST"}, + {0x005200, "FLOWER CANE"}, + {0x005300, "HILDEBEAR\'S CANE"}, + {0x005400, "HILDEBLUE\'S CANE"}, + {0x005500, "RABBIT WAND"}, + {0x005600, "PLANTAIN LEAF"}, + {0x005601, "FATSIA"}, + {0x005700, "DEMONIC FORK"}, + {0x005800, "STRIKER OF CHAO"}, + {0x005900, "BROOM"}, + {0x005A00, "PROPHETS OF MOTAV"}, + {0x005B00, "THE SIGH OF A GOD"}, + {0x005C00, "TWINKLE STAR"}, + {0x005D00, "PLANTAIN FAN"}, + {0x005E00, "TWIN BLAZE"}, + {0x005F00, "MARINA\'S BAG"}, + {0x006000, "DRAGON\'S CLAW"}, + {0x006100, "PANTHER\'S CLAW"}, + {0x006200, "S-RED\'S BLADE"}, + {0x006300, "PLANTAIN HUGE FAN"}, + {0x006400, "CHAMELEON SCYTHE"}, + {0x006500, "YASMINKOV 3000R"}, + {0x006600, "ANO RIFLE"}, + {0x006700, "BARANZ LAUNCHER"}, + {0x006800, "BRANCH OF PAKUPAKU"}, + {0x006900, "HEART OF POUMN"}, + {0x006A00, "YASMINKOV 2000H"}, + {0x006B00, "YASMINKOV 7000V"}, + {0x006C00, "YASMINKOV 9000M"}, + {0x006D00, "MASER BEAM"}, + {0x006D01, "POWER MASER"}, + {0x006E00, "GAME MAGAZINE"}, + {0x006F00, "FLOWER BOUQUET"}, + {0x007000, {"S-RANK SABER", true}}, + {0x007100, {"S-RANK SWORD", true}}, + {0x007200, {"S-RANK BLADE", true}}, + {0x007300, {"S-RANK PARTISAN", true}}, + {0x007400, {"S-RANK SLICER", true}}, + {0x007500, {"S-RANK GUN", true}}, + {0x007600, {"S-RANK RIFLE", true}}, + {0x007700, {"S-RANK MECHGUN", true}}, + {0x007800, {"S-RANK SHOT", true}}, + {0x007900, {"S-RANK CANE", true}}, + {0x007A00, {"S-RANK ROD", true}}, + {0x007B00, {"S-RANK WAND", true}}, + {0x007C00, {"S-RANK TWIN", true}}, + {0x007D00, {"S-RANK CLAW", true}}, + {0x007E00, {"S-RANK BAZOOKA", true}}, + {0x007F00, {"S-RANK NEEDLE", true}}, + {0x008000, {"S-RANK SCYTHE", true}}, + {0x008100, {"S-RANK HAMMER", true}}, + {0x008200, {"S-RANK MOON", true}}, + {0x008300, {"S-RANK PSYCHOGUN", true}}, + {0x008400, {"S-RANK PUNCH", true}}, + {0x008500, {"S-RANK WINDMILL", true}}, + {0x008600, {"S-RANK HARISEN", true}}, + {0x008700, {"S-RANK KATANA", true}}, + {0x008800, {"S-RANK J-CUTTER", true}}, + {0x008900, "MUSASHI"}, + {0x008901, "YAMATO"}, + {0x008902, "ASUKA"}, + {0x008903, "SANGE & YASHA"}, + {0x008A00, "SANGE"}, + {0x008A01, "YASHA"}, + {0x008A02, "KAMUI"}, + {0x008B00, "PHOTON LAUNCHER"}, + {0x008B01, "GUILTY LIGHT"}, + {0x008B02, "RED SCORPIO"}, + {0x008B03, "PHONON MASER"}, + {0x008C00, "TALIS"}, + {0x008C01, "MAHU"}, + {0x008C02, "HITOGATA"}, + {0x008C03, "DANCING HITOGATA"}, + {0x008C04, "KUNAI"}, + {0x008D00, "NUG-2000 BAZOOKA"}, + {0x008E00, "S-BERILL\'S HANDS #0"}, + {0x008E01, "S-BERILL\'S HANDS #1"}, + {0x008F00, "FLOWEN\'S SWORD (AUW 3060; GREENILL)"}, + {0x008F01, "FLOWEN\'S SWORD (AUW 3064; SKYLY)"}, + {0x008F02, "FLOWEN\'S SWORD (AUW 3067; BLUEFULL)"}, + {0x008F03, "FLOWEN\'S SWORD (AUW 3073; PURPLENUM)"}, + {0x008F04, "FLOWEN\'S SWORD (AUW 3077; PINKAL)"}, + {0x008F05, "FLOWEN\'S SWORD (AUW 3082; REDRIA)"}, + {0x008F06, "FLOWEN\'S SWORD (AUW 3083; ORAN)"}, + {0x008F07, "FLOWEN\'S SWORD (AUW 3084; YELLOWBOZE)"}, + {0x008F08, "FLOWEN\'S SWORD (AUW 3079; WHITILL)"}, + {0x009000, "DB\'S SWORD (AUW 3062; GREENILL)"}, + {0x009001, "DB\'S SWORD (AUW 3067; SKYLY)"}, + {0x009002, "DB\'S SWORD (AUW 3069; BLUEFULL)"}, + {0x009003, "DB\'S SWORD (AUW 3064; PURPLENUM)"}, + {0x009004, "DB\'S SWORD (AUW 3069; PINKAL)"}, + {0x009005, "DB\'S SWORD (AUW 3073; REDRIA)"}, + {0x009006, "DB\'S SWORD (AUW 3070; ORAN)"}, + {0x009007, "DB\'S SWORD (AUW 3075; YELLOWBOZE)"}, + {0x009008, "DB\'S SWORD (AUW 3077; WHITILL)"}, + {0x009100, "GI GUE BAZOOKA"}, + {0x009200, "GUARDIANNA"}, + {0x009300, "VIRIDIA CARD"}, + {0x009301, "GREENILL CARD"}, + {0x009302, "SKYLY CARD"}, + {0x009303, "BLUEFULL CARD"}, + {0x009304, "PURPLENUM CARD"}, + {0x009305, "PINKAL CARD"}, + {0x009306, "REDRIA CARD"}, + {0x009307, "ORAN CARD"}, + {0x009308, "YELLOWBOZE CARD"}, + {0x009309, "WHITILL CARD"}, + {0x009400, "MORNING GLORY"}, + {0x009500, "PARTISAN OF LIGHTING"}, + {0x009600, "GAL WIND"}, + {0x009700, "ZANBA"}, + {0x009800, "RIKA\'S CLAW"}, + {0x009900, "ANGEL HARP"}, + {0x009A00, "DEMOLITION COMET"}, + {0x009B00, "NEI\'S CLAW"}, + {0x009C00, "RAINBOW BATON"}, + {0x009D00, "DARK FLOW"}, + {0x009E00, "DARK METEOR"}, + {0x009F00, "DARK BRIDGE"}, + {0x00A000, "G-ASSASSIN\'S SABERS"}, + {0x00A100, "RAPPY\'S FAN"}, + {0x00A200, "BOOMA\'S CLAW"}, + {0x00A201, "GOBOOMA\'S CLAW"}, + {0x00A202, "GIGOBOOMA\'S CLAW"}, + {0x00A300, "RUBY BULLET"}, + {0x00A400, "AMORE ROSE"}, + {0x00A500, {"S-RANK SWORDS", true}}, + {0x00A600, {"S-RANK LAUNCHER", true}}, + {0x00A700, {"S-RANK CARD", true}}, + {0x00A800, {"S-RANK KNUCKLE", true}}, + {0x00A900, {"S-RANK AXE", true}}, + {0x00AA00, "SLICER OF FANATIC"}, + {0x00AB00, "LAME D\'ARGENT"}, + {0x00AC00, "EXCALIBUR"}, + {0x00AD03, "RAGE DE FEU"}, + {0x00AE00, "DAISY CHAIN"}, + {0x00AF00, "OPHELIE SEIZE"}, + {0x00B000, "MILLE MARTEAUX"}, + {0x00B100, "LE COGNEUR"}, + {0x00B200, "COMMANDER BLADE"}, + {0x00B300, "VIVIENNE"}, + {0x00B400, "KUSANAGI"}, + {0x00B500, "SACRED DUSTER"}, + {0x00B600, "GUREN"}, + {0x00B700, "SHOUREN"}, + {0x00B800, "JIZAI"}, + {0x00B900, "FLAMBERGE"}, + {0x00BA00, "YUNCHANG"}, + {0x00BB00, "SNAKE SPIRE"}, + {0x00BC00, "FLAPJACK FLAPPER"}, + {0x00BD00, "GETSUGASAN"}, + {0x00BE00, "MAGUWA"}, + {0x00BF00, "HEAVEN STRIKER"}, + {0x00C000, "CANNON ROUGE"}, + {0x00C100, "METEOR ROUGE"}, + {0x00C200, "SOLFERINO"}, + {0x00C300, "CLIO"}, + {0x00C400, "SIREN GLASS HAMMER"}, + {0x00C500, "GLIDE DIVINE"}, + {0x00C600, "SHICHISHITO"}, + {0x00C700, "MURASAME"}, + {0x00C800, "DAYLIGHT SCAR"}, + {0x00C900, "DECALOG"}, + {0x00CA00, "5TH ANNIV. BLADE"}, + {0x00CB00, "PRINCIPAL\'S GIFT PARASOL"}, + {0x00CC00, "AKIKO\'S CLEAVER"}, + {0x00CD00, "TANEGASHIMA"}, + {0x00CE00, "TREE CLIPPERS"}, + {0x00CF00, "NICE SHOT"}, + {0x00D200, "ANO BAZOOKA"}, + {0x00D300, "SYNTHESIZER"}, + {0x00D400, "BAMBOO SPEAR"}, + {0x00D500, "KAN\'EI TSUHO"}, + {0x00D600, "JITTE"}, + {0x00D700, "BUTTERFLY NET"}, + {0x00D800, "SYRINGE"}, + {0x00D900, "BATTLEDORE"}, + {0x00DA00, "RACKET"}, + {0x00DB00, "HAMMER"}, + {0x00DC00, "GREAT BOUQUET"}, + {0x00DD00, "TypeSA/Saber"}, + {0x00DE00, "TypeSL/Saber"}, + {0x00DE01, "TypeSL/Slicer"}, + {0x00DE02, "TypeSL/Claw"}, + {0x00DE03, "TypeSL/Katana"}, + {0x00DF00, "TypeJS/Saber"}, + {0x00DF01, "TypeJS/Slicer"}, + {0x00DF02, "TypeJS/J-Sword"}, + {0x00E000, "TypeSW/Sword"}, + {0x00E001, "TypeSW/Slicer"}, + {0x00E002, "TypeSW/J-Sword"}, + {0x00E100, "TypeRO/Sword"}, + {0x00E101, "TypeRO/Halbert"}, + {0x00E102, "TypeRO/Rod"}, + {0x00E200, "TypeBL/BLADE"}, + {0x00E300, "TypeKN/Blade"}, + {0x00E301, "TypeKN/Claw"}, + {0x00E400, "TypeHA/Halbert"}, + {0x00E401, "TypeHA/Rod"}, + {0x00E500, "TypeDS/D.Saber"}, + {0x00E501, "TypeDS/Rod"}, + {0x00E502, "TypeDS"}, + {0x00E600, "TypeCL/Claw"}, + {0x00E700, "TypeSS/SW"}, + {0x00E800, "TypeGU/Handgun"}, + {0x00E801, "TypeGU/Mechgun"}, + {0x00E900, "TypeRI/Rifle"}, + {0x00EA00, "TypeME/Mechgun"}, + {0x00EB00, "TypeSH/Shot"}, + {0x00EC00, "TypeWA/Wand"}, - // Armors (0101xx) - {0x010100, {"Frame", false}}, - {0x010101, {"Armor", false}}, - {0x010102, {"Psy Armor", false}}, - {0x010103, {"Giga Frame", false}}, - {0x010104, {"Soul Frame", false}}, - {0x010105, {"Cross Armor", false}}, - {0x010106, {"Solid Frame", false}}, - {0x010107, {"Brave Armor", false}}, - {0x010108, {"Hyper Frame", false}}, - {0x010109, {"Grand Armor", false}}, - {0x01010A, {"Shock Frame", false}}, - {0x01010B, {"King\'s Frame", false}}, - {0x01010C, {"Dragon Frame", false}}, - {0x01010D, {"Absorb Armor", false}}, - {0x01010E, {"Protect Frame", false}}, - {0x01010F, {"General Armor", false}}, - {0x010110, {"Perfect Frame", false}}, - {0x010111, {"Valiant Frame", false}}, - {0x010112, {"Imperial Armor", false}}, - {0x010113, {"Holiness Armor", false}}, - {0x010114, {"Guardian Armor", false}}, - {0x010115, {"Divinity Armor", false}}, - {0x010116, {"Ultimate Frame", false}}, - {0x010117, {"Celestial Armor", false}}, - {0x010118, "HUNTER FIELD"}, - {0x010119, "RANGER FIELD"}, - {0x01011A, "FORCE FIELD"}, - {0x01011B, "REVIVAL GARMENT"}, - {0x01011C, "SPIRIT GARMENT"}, - {0x01011D, "STINK FRAME"}, - {0x01011E, "D-PARTS Ver1.01"}, - {0x01011F, "D-PARTS Ver2.10"}, - {0x010120, "PARASITE WEAR:De Rol"}, - {0x010121, "PARASITE WEAR:Nelgal"}, - {0x010122, "PARASITE WEAR:Vajulla"}, - {0x010123, "SENSE PLATE"}, - {0x010124, "GRAVITON PLATE"}, - {0x010125, "ATTRIBUTE PLATE"}, - {0x010126, "FLOWEN\'S FRAME"}, - {0x010127, "CUSTOM FRAME Ver.00"}, - {0x010128, "DB\'s ARMOR"}, - {0x010129, "GUARD WAVE"}, - {0x01012A, "DF FIELD"}, - {0x01012B, "LUMINOUS FIELD"}, - {0x01012C, "CHU CHU FEVER"}, - {0x01012D, "LOVE HEART"}, - {0x01012E, "FLAME GARMENT"}, - {0x01012F, "VIRUS ARMOR:Lafuteria"}, - {0x010130, "BRIGHTNESS CIRCLE"}, - {0x010131, "AURA FIELD"}, - {0x010132, "ELECTRO FRAME"}, - {0x010133, "SACRED CLOTH"}, - {0x010134, "SMOKING PLATE"}, - {0x010135, "STAR CUIRASS"}, - {0x010136, "BLACK HOUND CUIRASS"}, - {0x010137, "MORNING PRAYER"}, - {0x010138, "BLACK ODOSHI DOMARU"}, - {0x010139, "RED ODOSHI DOMARU"}, - {0x01013A, "BLACK ODOSHI RED NIMAIDOU"}, - {0x01013B, "BLUE ODOSHI VIOLET NIMAIDOU"}, - {0x01013C, "DIRTY LIFE JACKET"}, - {0x01013E, "WEDDING DRESS"}, - {0x010140, "RED COAT"}, - {0x010141, "THIRTEEN"}, - {0x010142, "MOTHER GARB"}, - {0x010143, "MOTHER GARB+"}, - {0x010144, "DRESS PLATE"}, - {0x010145, "SWEETHEART"}, - {0x010146, "IGNITION CLOAK"}, - {0x010147, "CONGEAL CLOAK"}, - {0x010148, "TEMPEST CLOAK"}, - {0x010149, "CURSED CLOAK"}, - {0x01014A, "SELECT CLOAK"}, - {0x01014B, "SPIRIT CUIRASS"}, - {0x01014C, "REVIVAL CUIRASS"}, - {0x01014D, "ALLIANCE UNIFORM"}, - {0x01014E, "OFFICER UNIFORM"}, - {0x01014F, "COMMANDER UNIFORM"}, - {0x010150, "CRIMSON COAT"}, - {0x010151, "INFANTRY GEAR"}, - {0x010152, "LIEUTENANT GEAR"}, - {0x010153, "INFANTRY MANTLE"}, - {0x010154, "LIEUTENANT MANTLE"}, - {0x010155, "UNION FIELD"}, - {0x010156, "SAMURAI ARMOR"}, - {0x010157, "STEALTH SUIT"}, + // Armors (0101xx) + {0x010100, {"Frame", false}}, + {0x010101, {"Armor", false}}, + {0x010102, {"Psy Armor", false}}, + {0x010103, {"Giga Frame", false}}, + {0x010104, {"Soul Frame", false}}, + {0x010105, {"Cross Armor", false}}, + {0x010106, {"Solid Frame", false}}, + {0x010107, {"Brave Armor", false}}, + {0x010108, {"Hyper Frame", false}}, + {0x010109, {"Grand Armor", false}}, + {0x01010A, {"Shock Frame", false}}, + {0x01010B, {"King\'s Frame", false}}, + {0x01010C, {"Dragon Frame", false}}, + {0x01010D, {"Absorb Armor", false}}, + {0x01010E, {"Protect Frame", false}}, + {0x01010F, {"General Armor", false}}, + {0x010110, {"Perfect Frame", false}}, + {0x010111, {"Valiant Frame", false}}, + {0x010112, {"Imperial Armor", false}}, + {0x010113, {"Holiness Armor", false}}, + {0x010114, {"Guardian Armor", false}}, + {0x010115, {"Divinity Armor", false}}, + {0x010116, {"Ultimate Frame", false}}, + {0x010117, {"Celestial Armor", false}}, + {0x010118, "HUNTER FIELD"}, + {0x010119, "RANGER FIELD"}, + {0x01011A, "FORCE FIELD"}, + {0x01011B, "REVIVAL GARMENT"}, + {0x01011C, "SPIRIT GARMENT"}, + {0x01011D, "STINK FRAME"}, + {0x01011E, "D-PARTS Ver1.01"}, + {0x01011F, "D-PARTS Ver2.10"}, + {0x010120, "PARASITE WEAR:De Rol"}, + {0x010121, "PARASITE WEAR:Nelgal"}, + {0x010122, "PARASITE WEAR:Vajulla"}, + {0x010123, "SENSE PLATE"}, + {0x010124, "GRAVITON PLATE"}, + {0x010125, "ATTRIBUTE PLATE"}, + {0x010126, "FLOWEN\'S FRAME"}, + {0x010127, "CUSTOM FRAME Ver.00"}, + {0x010128, "DB\'s ARMOR"}, + {0x010129, "GUARD WAVE"}, + {0x01012A, "DF FIELD"}, + {0x01012B, "LUMINOUS FIELD"}, + {0x01012C, "CHU CHU FEVER"}, + {0x01012D, "LOVE HEART"}, + {0x01012E, "FLAME GARMENT"}, + {0x01012F, "VIRUS ARMOR:Lafuteria"}, + {0x010130, "BRIGHTNESS CIRCLE"}, + {0x010131, "AURA FIELD"}, + {0x010132, "ELECTRO FRAME"}, + {0x010133, "SACRED CLOTH"}, + {0x010134, "SMOKING PLATE"}, + {0x010135, "STAR CUIRASS"}, + {0x010136, "BLACK HOUND CUIRASS"}, + {0x010137, "MORNING PRAYER"}, + {0x010138, "BLACK ODOSHI DOMARU"}, + {0x010139, "RED ODOSHI DOMARU"}, + {0x01013A, "BLACK ODOSHI RED NIMAIDOU"}, + {0x01013B, "BLUE ODOSHI VIOLET NIMAIDOU"}, + {0x01013C, "DIRTY LIFE JACKET"}, + {0x01013E, "WEDDING DRESS"}, + {0x010140, "RED COAT"}, + {0x010141, "THIRTEEN"}, + {0x010142, "MOTHER GARB"}, + {0x010143, "MOTHER GARB+"}, + {0x010144, "DRESS PLATE"}, + {0x010145, "SWEETHEART"}, + {0x010146, "IGNITION CLOAK"}, + {0x010147, "CONGEAL CLOAK"}, + {0x010148, "TEMPEST CLOAK"}, + {0x010149, "CURSED CLOAK"}, + {0x01014A, "SELECT CLOAK"}, + {0x01014B, "SPIRIT CUIRASS"}, + {0x01014C, "REVIVAL CUIRASS"}, + {0x01014D, "ALLIANCE UNIFORM"}, + {0x01014E, "OFFICER UNIFORM"}, + {0x01014F, "COMMANDER UNIFORM"}, + {0x010150, "CRIMSON COAT"}, + {0x010151, "INFANTRY GEAR"}, + {0x010152, "LIEUTENANT GEAR"}, + {0x010153, "INFANTRY MANTLE"}, + {0x010154, "LIEUTENANT MANTLE"}, + {0x010155, "UNION FIELD"}, + {0x010156, "SAMURAI ARMOR"}, + {0x010157, "STEALTH SUIT"}, - // Shields (0102xx) - {0x010200, {"Barrier", false}}, - {0x010201, {"Shield", false}}, - {0x010202, {"Core Shield", false}}, - {0x010203, {"Giga Shield", false}}, - {0x010204, {"Soul Barrier", false}}, - {0x010205, {"Hard Shield", false}}, - {0x010206, {"Brave Barrier", false}}, - {0x010207, {"Solid Shield", false}}, - {0x010208, {"Flame Barrier", false}}, - {0x010209, {"Plasma Barrier", false}}, - {0x01020A, {"Freeze Barrier", false}}, - {0x01020B, {"Psychic Barrier", false}}, - {0x01020C, {"General Shield", false}}, - {0x01020D, {"Protect Barrier", false}}, - {0x01020E, {"Glorious Shield", false}}, - {0x01020F, {"Imperial Barrier", false}}, - {0x010210, {"Guardian Shield", false}}, - {0x010211, {"Divinity Barrier", false}}, - {0x010212, {"Ultimate Shield", false}}, - {0x010213, {"Spiritual Shield", false}}, - {0x010214, {"Celestial Shield", false}}, - {0x010215, "INVISIBLE GUARD"}, - {0x010216, "SACRED GUARD"}, - {0x010217, "S-PARTS Ver1.16"}, - {0x010218, "S-PARTS Ver2.01"}, - {0x010219, "LIGHT RELIEF"}, - {0x01021A, "SHIELD OF DELSABER"}, - {0x01021B, "FORCE WALL"}, - {0x01021C, "RANGER WALL"}, - {0x01021D, "HUNTER WALL"}, - {0x01021E, "ATTRIBUTE WALL"}, - {0x01021F, "SECRET GEAR"}, - {0x010220, "COMBAT GEAR"}, - {0x010221, "PROTO REGENE GEAR"}, - {0x010222, "REGENERATE GEAR"}, - {0x010223, "REGENE GEAR ADV."}, - {0x010224, "FLOWEN\'S SHIELD"}, - {0x010225, "CUSTOM BARRIER Ver.00"}, - {0x010226, "DB\'S SHIELD"}, - {0x010227, "RED RING"}, - {0x010228, "TRIPOLIC SHIELD"}, - {0x010229, "STANDSTILL SHIELD"}, - {0x01022A, "SAFETY HEART"}, - {0x01022B, "KASAMI BRACER"}, - {0x01022C, "GODS SHIELD SUZAKU"}, - {0x01022D, "GODS SHIELD GENBU"}, - {0x01022E, "GODS SHIELD BYAKKO"}, - {0x01022F, "GODS SHIELD SEIRYU"}, - {0x010230, "HUNTER\'S SHELL"}, - {0x010231, "RICO\'S GLASSES"}, - {0x010232, "RICO\'S EARRING"}, - {0x010235, {"SECURE FEET", false}}, - {0x01023A, {"RESTA MERGE", false}}, - {0x01023B, {"ANTI MERGE", false}}, - {0x01023C, {"SHIFTA MERGE", false}}, - {0x01023D, {"DEBAND MERGE", false}}, - {0x01023E, {"FOIE MERGE", false}}, - {0x01023F, {"GIFOIE MERGE", false}}, - {0x010240, {"RAFOIE MERGE", false}}, - {0x010241, {"RED MERGE", false}}, - {0x010242, {"BARTA MERGE", false}}, - {0x010243, {"GIBARTA MERGE", false}}, - {0x010244, {"RABARTA MERGE", false}}, - {0x010245, {"BLUE MERGE", false}}, - {0x010246, {"ZONDE MERGE", false}}, - {0x010247, {"GIZONDE MERGE", false}}, - {0x010248, {"RAZONDE MERGE", false}}, - {0x010249, {"YELLOW MERGE", false}}, - {0x01024A, {"RECOVERY BARRIER", false}}, - {0x01024B, {"ASSIST BARRIER", false}}, - {0x01024C, {"RED BARRIER", false}}, - {0x01024D, {"BLUE BARRIER", false}}, - {0x01024E, {"YELLOW BARRIER", false}}, - {0x01024F, "WEAPONS GOLD SHIELD"}, - {0x010250, "BLACK GEAR"}, - {0x010251, "WORKS GUARD"}, - {0x010252, "RAGOL RING"}, - {0x010253, "BLUE RING (7 Colors)"}, - {0x010259, "BLUE RING"}, - {0x01025F, "GREEN RING"}, - {0x010266, "YELLOW RING"}, - {0x01026C, "PURPLE RING"}, - {0x010275, "WHITE RING"}, - {0x010280, "BLACK RING"}, - {0x010283, "WEAPONS SILVER SHIELD"}, - {0x010284, "WEAPONS COPPER SHIELD"}, - {0x010285, "GRATIA"}, - {0x010286, "TRIPOLIC REFLECTOR"}, - {0x010287, "STRIKER PLUS"}, - {0x010288, "REGENERATE GEAR B.P."}, - {0x010289, "RUPIKA"}, - {0x01028A, "YATA MIRROR"}, - {0x01028B, "BUNNY EARS"}, - {0x01028C, "CAT EARS"}, - {0x01028D, "THREE SEALS"}, - {0x01028F, "DF SHIELD"}, - {0x010290, "FROM THE DEPTHS"}, - {0x010291, "DE ROL LE SHIELD"}, - {0x010292, "HONEYCOMB REFLECTOR"}, - {0x010293, "EPSIGUARD"}, - {0x010294, "ANGEL RING"}, - {0x010295, "UNION GUARD"}, - {0x010297, "UNION"}, - {0x010298, "BLACK SHIELD UNION GUARD"}, - {0x010299, "STINK SHIELD"}, - {0x01029A, "BLACK"}, - {0x01029B, "GENPEI Heightened"}, - {0x01029C, "GENPEI Greenill"}, - {0x01029D, "GENPEI Skyly"}, - {0x01029E, "GENPEI Bluefull"}, - {0x01029F, "GENPEI Purplenum"}, - {0x0102A0, "GENPEI Pinkal"}, - {0x0102A1, "GENPEI Redria"}, - {0x0102A2, "GENPEI Oran"}, - {0x0102A3, "GENPEI Yellowboze"}, - {0x0102A4, "GENPEI Whitill"}, + // Shields (0102xx) + {0x010200, {"Barrier", false}}, + {0x010201, {"Shield", false}}, + {0x010202, {"Core Shield", false}}, + {0x010203, {"Giga Shield", false}}, + {0x010204, {"Soul Barrier", false}}, + {0x010205, {"Hard Shield", false}}, + {0x010206, {"Brave Barrier", false}}, + {0x010207, {"Solid Shield", false}}, + {0x010208, {"Flame Barrier", false}}, + {0x010209, {"Plasma Barrier", false}}, + {0x01020A, {"Freeze Barrier", false}}, + {0x01020B, {"Psychic Barrier", false}}, + {0x01020C, {"General Shield", false}}, + {0x01020D, {"Protect Barrier", false}}, + {0x01020E, {"Glorious Shield", false}}, + {0x01020F, {"Imperial Barrier", false}}, + {0x010210, {"Guardian Shield", false}}, + {0x010211, {"Divinity Barrier", false}}, + {0x010212, {"Ultimate Shield", false}}, + {0x010213, {"Spiritual Shield", false}}, + {0x010214, {"Celestial Shield", false}}, + {0x010215, "INVISIBLE GUARD"}, + {0x010216, "SACRED GUARD"}, + {0x010217, "S-PARTS Ver1.16"}, + {0x010218, "S-PARTS Ver2.01"}, + {0x010219, "LIGHT RELIEF"}, + {0x01021A, "SHIELD OF DELSABER"}, + {0x01021B, "FORCE WALL"}, + {0x01021C, "RANGER WALL"}, + {0x01021D, "HUNTER WALL"}, + {0x01021E, "ATTRIBUTE WALL"}, + {0x01021F, "SECRET GEAR"}, + {0x010220, "COMBAT GEAR"}, + {0x010221, "PROTO REGENE GEAR"}, + {0x010222, "REGENERATE GEAR"}, + {0x010223, "REGENE GEAR ADV."}, + {0x010224, "FLOWEN\'S SHIELD"}, + {0x010225, "CUSTOM BARRIER Ver.00"}, + {0x010226, "DB\'S SHIELD"}, + {0x010227, "RED RING"}, + {0x010228, "TRIPOLIC SHIELD"}, + {0x010229, "STANDSTILL SHIELD"}, + {0x01022A, "SAFETY HEART"}, + {0x01022B, "KASAMI BRACER"}, + {0x01022C, "GODS SHIELD SUZAKU"}, + {0x01022D, "GODS SHIELD GENBU"}, + {0x01022E, "GODS SHIELD BYAKKO"}, + {0x01022F, "GODS SHIELD SEIRYU"}, + {0x010230, "HUNTER\'S SHELL"}, + {0x010231, "RICO\'S GLASSES"}, + {0x010232, "RICO\'S EARRING"}, + {0x010235, {"SECURE FEET", false}}, + {0x01023A, {"RESTA MERGE", false}}, + {0x01023B, {"ANTI MERGE", false}}, + {0x01023C, {"SHIFTA MERGE", false}}, + {0x01023D, {"DEBAND MERGE", false}}, + {0x01023E, {"FOIE MERGE", false}}, + {0x01023F, {"GIFOIE MERGE", false}}, + {0x010240, {"RAFOIE MERGE", false}}, + {0x010241, {"RED MERGE", false}}, + {0x010242, {"BARTA MERGE", false}}, + {0x010243, {"GIBARTA MERGE", false}}, + {0x010244, {"RABARTA MERGE", false}}, + {0x010245, {"BLUE MERGE", false}}, + {0x010246, {"ZONDE MERGE", false}}, + {0x010247, {"GIZONDE MERGE", false}}, + {0x010248, {"RAZONDE MERGE", false}}, + {0x010249, {"YELLOW MERGE", false}}, + {0x01024A, {"RECOVERY BARRIER", false}}, + {0x01024B, {"ASSIST BARRIER", false}}, + {0x01024C, {"RED BARRIER", false}}, + {0x01024D, {"BLUE BARRIER", false}}, + {0x01024E, {"YELLOW BARRIER", false}}, + {0x01024F, "WEAPONS GOLD SHIELD"}, + {0x010250, "BLACK GEAR"}, + {0x010251, "WORKS GUARD"}, + {0x010252, "RAGOL RING"}, + {0x010253, "BLUE RING (7 Colors)"}, + {0x010259, "BLUE RING"}, + {0x01025F, "GREEN RING"}, + {0x010266, "YELLOW RING"}, + {0x01026C, "PURPLE RING"}, + {0x010275, "WHITE RING"}, + {0x010280, "BLACK RING"}, + {0x010283, "WEAPONS SILVER SHIELD"}, + {0x010284, "WEAPONS COPPER SHIELD"}, + {0x010285, "GRATIA"}, + {0x010286, "TRIPOLIC REFLECTOR"}, + {0x010287, "STRIKER PLUS"}, + {0x010288, "REGENERATE GEAR B.P."}, + {0x010289, "RUPIKA"}, + {0x01028A, "YATA MIRROR"}, + {0x01028B, "BUNNY EARS"}, + {0x01028C, "CAT EARS"}, + {0x01028D, "THREE SEALS"}, + {0x01028F, "DF SHIELD"}, + {0x010290, "FROM THE DEPTHS"}, + {0x010291, "DE ROL LE SHIELD"}, + {0x010292, "HONEYCOMB REFLECTOR"}, + {0x010293, "EPSIGUARD"}, + {0x010294, "ANGEL RING"}, + {0x010295, "UNION GUARD"}, + {0x010297, "UNION"}, + {0x010298, "BLACK SHIELD UNION GUARD"}, + {0x010299, "STINK SHIELD"}, + {0x01029A, "BLACK"}, + {0x01029B, "GENPEI Heightened"}, + {0x01029C, "GENPEI Greenill"}, + {0x01029D, "GENPEI Skyly"}, + {0x01029E, "GENPEI Bluefull"}, + {0x01029F, "GENPEI Purplenum"}, + {0x0102A0, "GENPEI Pinkal"}, + {0x0102A1, "GENPEI Redria"}, + {0x0102A2, "GENPEI Oran"}, + {0x0102A3, "GENPEI Yellowboze"}, + {0x0102A4, "GENPEI Whitill"}, - // Units (0103xx) - {0x010300, {"Knight/Power", false}}, - {0x010301, {"General/Power", false}}, - {0x010302, {"Ogre/Power", false}}, - {0x010303, "God/Power"}, - {0x010304, {"Priest/Mind", false}}, - {0x010305, {"General/Mind", false}}, - {0x010306, {"Angel/Mind", false}}, - {0x010307, "God/Mind"}, - {0x010308, {"Marksman/Arm", false}}, - {0x010309, {"General/Arm", false}}, - {0x01030A, {"Elf/Arm", false}}, - {0x01030B, "God/Arm"}, - {0x01030C, {"Thief/Legs", false}}, - {0x01030D, {"General/Legs", false}}, - {0x01030E, {"Elf/Legs", false}}, - {0x01030F, "God/Legs"}, - {0x010310, {"Digger/HP", false}}, - {0x010311, {"General/HP", false}}, - {0x010312, {"Dragon/HP", false}}, - {0x010313, "God/HP"}, - {0x010314, {"Magician/TP", false}}, - {0x010315, {"General/TP", false}}, - {0x010316, {"Angel/TP", false}}, - {0x010317, "God/TP"}, - {0x010318, {"Warrior/Body", false}}, - {0x010319, {"General/Body", false}}, - {0x01031A, {"Metal/Body", false}}, - {0x01031B, "God/Body"}, - {0x01031C, {"Angel/Luck", false}}, - {0x01031D, "God/Luck"}, - {0x01031E, {"Master/Ability", false}}, - {0x01031F, {"Hero/Ability", false}}, - {0x010320, "God/Ability"}, - {0x010321, {"Resist/Fire", false}}, - {0x010322, {"Resist/Flame", false}}, - {0x010323, {"Resist/Burning", false}}, - {0x010324, {"Resist/Cold", false}}, - {0x010325, {"Resist/Freeze", false}}, - {0x010326, {"Resist/Blizzard", false}}, - {0x010327, {"Resist/Shock", false}}, - {0x010328, {"Resist/Thunder", false}}, - {0x010329, {"Resist/Storm", false}}, - {0x01032A, {"Resist/Light", false}}, - {0x01032B, {"Resist/Saint", false}}, - {0x01032C, {"Resist/Holy", false}}, - {0x01032D, {"Resist/Dark", false}}, - {0x01032E, {"Resist/Evil", false}}, - {0x01032F, {"Resist/Devil", false}}, - {0x010330, {"All/Resist", false}}, - {0x010331, {"Super/Resist", false}}, - {0x010332, "Perfect/Resist"}, - {0x010333, {"HP/Restorate", false}}, - {0x010334, {"HP/Generate", false}}, - {0x010335, {"HP/Revival", false}}, - {0x010336, {"TP/Restorate", false}}, - {0x010337, {"TP/Generate", false}}, - {0x010338, {"TP/Revival", false}}, - {0x010339, {"PB/Amplifier", false}}, - {0x01033A, {"PB/Generate", false}}, - {0x01033B, {"PB/Create", false}}, - {0x01033C, {"Wizard/Technique", false}}, - {0x01033D, {"Devil/Technique", false}}, - {0x01033E, "God/Technique"}, - {0x01033F, {"General/Battle", false}}, - {0x010340, {"Devil/Battle", false}}, - {0x010341, "God/Battle"}, - {0x010342, "Cure/Poison"}, - {0x010343, "Cure/Paralysis"}, - {0x010344, "Cure/Slow"}, - {0x010345, "Cure/Confuse"}, - {0x010346, "Cure/Freeze"}, - {0x010347, "Cure/Shock"}, - {0x010348, "Yasakani Magatama"}, - {0x010349, "V101"}, - {0x01034A, "V501"}, - {0x01034B, "V502"}, - {0x01034C, "V801"}, - {0x01034D, "LIMITER"}, - {0x01034E, "ADEPT"}, - {0x01034F, "SWORDSMAN LORE"}, - {0x010350, "PROOF OF SWORD-SAINT"}, - {0x010351, "SMARTLINK"}, - {0x010352, "DIVINE PROTECTION"}, - {0x010353, "Heavenly/Battle"}, - {0x010354, "Heavenly/Power"}, - {0x010355, "Heavenly/Mind"}, - {0x010356, "Heavenly/Arms"}, - {0x010357, "Heavenly/Legs"}, - {0x010358, "Heavenly/Body"}, - {0x010359, "Heavenly/Luck"}, - {0x01035A, "Heavenly/Ability"}, - {0x01035B, "Centurion/Ability"}, - {0x01035C, "Friend Ring"}, - {0x01035D, "Heavenly/HP"}, - {0x01035E, "Heavenly/TP"}, - {0x01035F, "Heavenly/Resist"}, - {0x010360, "Heavenly/Technique"}, - {0x010361, "HP/Resurrection"}, - {0x010362, "TP/Resurrection"}, - {0x010363, "PB/Increase"}, + // Units (0103xx) + {0x010300, {"Knight/Power", false}}, + {0x010301, {"General/Power", false}}, + {0x010302, {"Ogre/Power", false}}, + {0x010303, "God/Power"}, + {0x010304, {"Priest/Mind", false}}, + {0x010305, {"General/Mind", false}}, + {0x010306, {"Angel/Mind", false}}, + {0x010307, "God/Mind"}, + {0x010308, {"Marksman/Arm", false}}, + {0x010309, {"General/Arm", false}}, + {0x01030A, {"Elf/Arm", false}}, + {0x01030B, "God/Arm"}, + {0x01030C, {"Thief/Legs", false}}, + {0x01030D, {"General/Legs", false}}, + {0x01030E, {"Elf/Legs", false}}, + {0x01030F, "God/Legs"}, + {0x010310, {"Digger/HP", false}}, + {0x010311, {"General/HP", false}}, + {0x010312, {"Dragon/HP", false}}, + {0x010313, "God/HP"}, + {0x010314, {"Magician/TP", false}}, + {0x010315, {"General/TP", false}}, + {0x010316, {"Angel/TP", false}}, + {0x010317, "God/TP"}, + {0x010318, {"Warrior/Body", false}}, + {0x010319, {"General/Body", false}}, + {0x01031A, {"Metal/Body", false}}, + {0x01031B, "God/Body"}, + {0x01031C, {"Angel/Luck", false}}, + {0x01031D, "God/Luck"}, + {0x01031E, {"Master/Ability", false}}, + {0x01031F, {"Hero/Ability", false}}, + {0x010320, "God/Ability"}, + {0x010321, {"Resist/Fire", false}}, + {0x010322, {"Resist/Flame", false}}, + {0x010323, {"Resist/Burning", false}}, + {0x010324, {"Resist/Cold", false}}, + {0x010325, {"Resist/Freeze", false}}, + {0x010326, {"Resist/Blizzard", false}}, + {0x010327, {"Resist/Shock", false}}, + {0x010328, {"Resist/Thunder", false}}, + {0x010329, {"Resist/Storm", false}}, + {0x01032A, {"Resist/Light", false}}, + {0x01032B, {"Resist/Saint", false}}, + {0x01032C, {"Resist/Holy", false}}, + {0x01032D, {"Resist/Dark", false}}, + {0x01032E, {"Resist/Evil", false}}, + {0x01032F, {"Resist/Devil", false}}, + {0x010330, {"All/Resist", false}}, + {0x010331, {"Super/Resist", false}}, + {0x010332, "Perfect/Resist"}, + {0x010333, {"HP/Restorate", false}}, + {0x010334, {"HP/Generate", false}}, + {0x010335, {"HP/Revival", false}}, + {0x010336, {"TP/Restorate", false}}, + {0x010337, {"TP/Generate", false}}, + {0x010338, {"TP/Revival", false}}, + {0x010339, {"PB/Amplifier", false}}, + {0x01033A, {"PB/Generate", false}}, + {0x01033B, {"PB/Create", false}}, + {0x01033C, {"Wizard/Technique", false}}, + {0x01033D, {"Devil/Technique", false}}, + {0x01033E, "God/Technique"}, + {0x01033F, {"General/Battle", false}}, + {0x010340, {"Devil/Battle", false}}, + {0x010341, "God/Battle"}, + {0x010342, "Cure/Poison"}, + {0x010343, "Cure/Paralysis"}, + {0x010344, "Cure/Slow"}, + {0x010345, "Cure/Confuse"}, + {0x010346, "Cure/Freeze"}, + {0x010347, "Cure/Shock"}, + {0x010348, "Yasakani Magatama"}, + {0x010349, "V101"}, + {0x01034A, "V501"}, + {0x01034B, "V502"}, + {0x01034C, "V801"}, + {0x01034D, "LIMITER"}, + {0x01034E, "ADEPT"}, + {0x01034F, "SWORDSMAN LORE"}, + {0x010350, "PROOF OF SWORD-SAINT"}, + {0x010351, "SMARTLINK"}, + {0x010352, "DIVINE PROTECTION"}, + {0x010353, "Heavenly/Battle"}, + {0x010354, "Heavenly/Power"}, + {0x010355, "Heavenly/Mind"}, + {0x010356, "Heavenly/Arms"}, + {0x010357, "Heavenly/Legs"}, + {0x010358, "Heavenly/Body"}, + {0x010359, "Heavenly/Luck"}, + {0x01035A, "Heavenly/Ability"}, + {0x01035B, "Centurion/Ability"}, + {0x01035C, "Friend Ring"}, + {0x01035D, "Heavenly/HP"}, + {0x01035E, "Heavenly/TP"}, + {0x01035F, "Heavenly/Resist"}, + {0x010360, "Heavenly/Technique"}, + {0x010361, "HP/Resurrection"}, + {0x010362, "TP/Resurrection"}, + {0x010363, "PB/Increase"}, - // Mags (02xxxx) - {0x020000, {"Mag", false}}, - {0x020100, {"Varuna", false}}, - {0x020200, {"Mitra", false}}, - {0x020300, {"Surya", false}}, - {0x020400, {"Vayu", false}}, - {0x020500, {"Varaha", false}}, - {0x020600, {"Kama", false}}, - {0x020700, {"Ushasu", false}}, - {0x020800, {"Apsaras", false}}, - {0x020900, {"Kumara", false}}, - {0x020A00, {"Kaitabha", false}}, - {0x020B00, {"Tapas", false}}, - {0x020C00, {"Bhirava", false}}, - {0x020D00, {"Kalki", false}}, - {0x020E00, {"Rudra", false}}, - {0x020F00, {"Marutah", false}}, - {0x021000, {"Yaksa", false}}, - {0x021100, {"Sita", false}}, - {0x021200, {"Garuda", false}}, - {0x021300, {"Nandin", false}}, - {0x021400, {"Ashvinau", false}}, - {0x021500, {"Ribhava", false}}, - {0x021600, {"Soma", false}}, - {0x021700, {"Ila", false}}, - {0x021800, {"Durga", false}}, - {0x021900, {"Vritra", false}}, - {0x021A00, {"Namuci", false}}, - {0x021B00, {"Sumba", false}}, - {0x021C00, {"Naga", false}}, - {0x021D00, {"Pitri", false}}, - {0x021E00, {"Kabanda", false}}, - {0x021F00, {"Ravana", false}}, - {0x022000, {"Marica", false}}, - {0x022100, {"Soniti", false}}, - {0x022200, {"Preta", false}}, - {0x022300, {"Andhaka", false}}, - {0x022400, {"Bana", false}}, - {0x022500, {"Naraka", false}}, - {0x022600, {"Madhu", false}}, - {0x022700, {"Churel", false}}, - {0x022800, "ROBOCHAO"}, - {0x022900, "OPA-OPA"}, - {0x022A00, "PIAN"}, - {0x022B00, "CHAO"}, - {0x022C00, "CHU CHU"}, - {0x022D00, "KAPU KAPU"}, - {0x022E00, "ANGEL\'S WING"}, - {0x022F00, "DEVIL\'S WING"}, - {0x023000, "ELENOR"}, - {0x023100, "MARK3"}, - {0x023200, "MASTER SYSTEM"}, - {0x023300, "GENESIS"}, - {0x023400, "SEGA SATURN"}, - {0x023500, "DREAMCAST"}, - {0x023600, "HAMBURGER"}, - {0x023700, "PANZER\'S TAIL"}, - {0x023800, "DAVIL\'S TAIL"}, - {0x023900, "Deva"}, - {0x023A00, "Rati"}, - {0x023B00, "Savitri"}, - {0x023C00, "Rukmin"}, - {0x023D00, "Pushan"}, - {0x023E00, "Diwari"}, - {0x023F00, "Sato"}, - {0x024000, "Bhima"}, - {0x024100, "Nidra"}, + // Mags (02xxxx) + {0x020000, {"Mag", false}}, + {0x020100, {"Varuna", false}}, + {0x020200, {"Mitra", false}}, + {0x020300, {"Surya", false}}, + {0x020400, {"Vayu", false}}, + {0x020500, {"Varaha", false}}, + {0x020600, {"Kama", false}}, + {0x020700, {"Ushasu", false}}, + {0x020800, {"Apsaras", false}}, + {0x020900, {"Kumara", false}}, + {0x020A00, {"Kaitabha", false}}, + {0x020B00, {"Tapas", false}}, + {0x020C00, {"Bhirava", false}}, + {0x020D00, {"Kalki", false}}, + {0x020E00, {"Rudra", false}}, + {0x020F00, {"Marutah", false}}, + {0x021000, {"Yaksa", false}}, + {0x021100, {"Sita", false}}, + {0x021200, {"Garuda", false}}, + {0x021300, {"Nandin", false}}, + {0x021400, {"Ashvinau", false}}, + {0x021500, {"Ribhava", false}}, + {0x021600, {"Soma", false}}, + {0x021700, {"Ila", false}}, + {0x021800, {"Durga", false}}, + {0x021900, {"Vritra", false}}, + {0x021A00, {"Namuci", false}}, + {0x021B00, {"Sumba", false}}, + {0x021C00, {"Naga", false}}, + {0x021D00, {"Pitri", false}}, + {0x021E00, {"Kabanda", false}}, + {0x021F00, {"Ravana", false}}, + {0x022000, {"Marica", false}}, + {0x022100, {"Soniti", false}}, + {0x022200, {"Preta", false}}, + {0x022300, {"Andhaka", false}}, + {0x022400, {"Bana", false}}, + {0x022500, {"Naraka", false}}, + {0x022600, {"Madhu", false}}, + {0x022700, {"Churel", false}}, + {0x022800, "ROBOCHAO"}, + {0x022900, "OPA-OPA"}, + {0x022A00, "PIAN"}, + {0x022B00, "CHAO"}, + {0x022C00, "CHU CHU"}, + {0x022D00, "KAPU KAPU"}, + {0x022E00, "ANGEL\'S WING"}, + {0x022F00, "DEVIL\'S WING"}, + {0x023000, "ELENOR"}, + {0x023100, "MARK3"}, + {0x023200, "MASTER SYSTEM"}, + {0x023300, "GENESIS"}, + {0x023400, "SEGA SATURN"}, + {0x023500, "DREAMCAST"}, + {0x023600, "HAMBURGER"}, + {0x023700, "PANZER\'S TAIL"}, + {0x023800, "DAVIL\'S TAIL"}, + {0x023900, "Deva"}, + {0x023A00, "Rati"}, + {0x023B00, "Savitri"}, + {0x023C00, "Rukmin"}, + {0x023D00, "Pushan"}, + {0x023E00, "Diwari"}, + {0x023F00, "Sato"}, + {0x024000, "Bhima"}, + {0x024100, "Nidra"}, - // Tools (03xxxx) - {0x030000, {"Monomate", false}}, - {0x030001, {"Dimate", false}}, - {0x030002, {"Trimate", false}}, - {0x030100, {"Monofluid", false}}, - {0x030101, {"Difluid", false}}, - {0x030102, {"Trifluid", false}}, - {0x030200, {"", false}}, // Special-cased in name_for_item - {0x030300, {"Sol Atomizer", false}}, - {0x030400, {"Moon Atomizer", false}}, - {0x030500, {"Star Atomizer", false}}, - {0x030600, {"Antidote", false}}, - {0x030601, {"Antiparalysis", false}}, - {0x030700, {"Telepipe", false}}, - {0x030800, {"Trap Vision", false}}, - {0x030900, {"Scape Doll", false}}, - {0x030A00, {"Monogrinder", false}}, - {0x030A01, {"Digrinder", false}}, - {0x030A02, {"Trigrinder", false}}, - {0x030B00, {"Power Material", false}}, - {0x030B01, {"Mind Material", false}}, - {0x030B02, {"Evade Material", false}}, - {0x030B03, {"HP Material", false}}, - {0x030B04, {"TP Material", false}}, - {0x030B05, {"Def Material", false}}, - {0x030B06, {"Luck Material", false}}, - {0x030C00, "Cell Of MAG 502"}, - {0x030C01, "Cell Of MAG 213"}, - {0x030C02, "Parts Of RoboChao"}, - {0x030C03, "Heart Of Opa Opa"}, - {0x030C04, "Heart Of Pian"}, - {0x030C05, "Heart Of Chao"}, - {0x030D00, "Sorcerer\'s Right Arm"}, - {0x030D01, "S-beat\'s Arms"}, - {0x030D02, "P-arm\'s Arms"}, - {0x030D03, "Delsaber\'s Right Arm"}, - {0x030D04, "C-bringer\'s Right Arm"}, - {0x030D05, "Delsaber\'s Left Arm"}, - {0x030D06, "S-red\'s Arms"}, - {0x030D07, "Dragon\'s Claw"}, - {0x030D08, "Hildebear\'s Head"}, - {0x030D09, "Hildeblue\'s Head"}, - {0x030D0A, "Parts of Baranz"}, - {0x030D0B, "Belra\'s Right Arm"}, - {0x030D0C, "Gi Gue\'s Body"}, - {0x030D0D, "Sinow Berill\'s Arms"}, - {0x030D0E, "G-Assassin\'s Arms"}, - {0x030D0F, "Booma\'s Right Arm"}, - {0x030D10, "Gobooma\'s Right Arm"}, - {0x030D11, "Gigobooma\'s Right Arm"}, - {0x030D12, "Gal Gryphon's Wing"}, - {0x030D13, "Rappy\'s Wing"}, - {0x030D14, "Cladding of Epsilon"}, - {0x030D15, "De Rol Le Shell"}, - {0x030E00, "Berill Photon"}, - {0x030E01, "Parasitic gene \"Flow\""}, - {0x030E02, "Magic stone \"Iritista\""}, - {0x030E03, "Blue-black stone"}, - {0x030E04, "Syncesta"}, - {0x030E05, "Magic Water"}, - {0x030E06, "Parasitic cell Type-D"}, - {0x030E07, "magic rock \"Heart Key\""}, - {0x030E08, "magic rock \"Moola\""}, - {0x030E09, "Star Amplifier"}, - {0x030E0A, "Book of HITOGATA"}, - {0x030E0B, "Heart of Chu Chu"}, - {0x030E0C, "Parts of EGG BLASTER"}, - {0x030E0D, "Heart of Angel"}, - {0x030E0E, "Heart of Devil"}, - {0x030E0F, "Kit of Hamburger"}, - {0x030E10, "Panther\'s Spirit"}, - {0x030E11, "Kit of MARK3"}, - {0x030E12, "Kit of MASTER SYSTEM"}, - {0x030E13, "Kit of GENESIS"}, - {0x030E14, "Kit of SEGA SATURN"}, - {0x030E15, "Kit of DREAMCAST"}, - {0x030E16, {"Amplifier of Resta", false}}, - {0x030E17, {"Amplifier of Anti", false}}, - {0x030E18, {"Amplifier of Shifta", false}}, - {0x030E19, {"Amplifier of Deband", false}}, - {0x030E1A, {"Amplifier of Foie", false}}, - {0x030E1B, {"Amplifier of Gifoie", false}}, - {0x030E1C, {"Amplifier of Rafoie", false}}, - {0x030E1D, {"Amplifier of Barta", false}}, - {0x030E1E, {"Amplifier of Gibarta", false}}, - {0x030E1F, {"Amplifier of Rabarta", false}}, - {0x030E20, {"Amplifier of Zonde", false}}, - {0x030E21, {"Amplifier of Gizonde", false}}, - {0x030E22, {"Amplifier of Razonde", false}}, - {0x030E23, {"Amplifier of Red", false}}, - {0x030E24, {"Amplifier of Blue", false}}, - {0x030E25, {"Amplifier of Yellow", false}}, - {0x030E26, "Heart of KAPU KAPU"}, - {0x030E27, "Photon Booster"}, - {0x030F00, "AddSlot"}, - {0x031000, "Photon Drop"}, - {0x031001, "Photon Sphere"}, - {0x031002, "Photon Crystal"}, - {0x031003, "Secret Lottery Ticket"}, - {0x031100, "Book of KATANA1"}, - {0x031101, "Book of KATANA2"}, - {0x031102, "Book of KATANA3"}, - {0x031200, "Weapons Bronze Badge"}, - {0x031201, "Weapons Silver Badge"}, - {0x031202, "Weapons Gold Badge"}, - {0x031203, "Weapons Crystal Badge"}, - {0x031204, "Weapons Steel Badge"}, - {0x031205, "Weapons Aluminum Badge"}, - {0x031206, "Weapons Leather Badge"}, - {0x031207, "Weapons Bone Badge"}, - {0x031208, "Letter of appreciation"}, - {0x031209, "Autograph Album"}, - {0x03120A, "Valentine\'s Chocolate"}, - {0x03120B, "New Year\'s Card"}, - {0x03120C, "Christmas Card"}, - {0x03120D, "Birthday Card"}, - {0x03120E, "Proof of Sonic Team"}, - {0x03120F, "Special Event Ticket"}, - {0x031210, "Flower Bouquet"}, - {0x031211, "Cake"}, - {0x031212, "Accessories"}, - {0x031213, "Mr.Naka\'s Business Card"}, - {0x031300, "Present"}, - {0x031400, "Chocolate"}, - {0x031401, "Candy"}, - {0x031402, "Cake"}, - {0x031403, "Silver Badge"}, - {0x031404, "Gold Badge"}, - {0x031405, "Crystal Badge"}, - {0x031406, "Iron Badge"}, - {0x031407, "Aluminum Badge"}, - {0x031408, "Leather Badge"}, - {0x031409, "Bone Badge"}, - {0x03140A, "Bouquet"}, - {0x03140B, "Decoction"}, - {0x031500, "Christmas Present"}, - {0x031501, "Easter Egg"}, - {0x031502, "Jack-O\'-Lantern"}, - {0x031600, "DISK Vol.1"}, - {0x031601, "DISK Vol.2"}, - {0x031602, "DISK Vol.3"}, - {0x031603, "DISK Vol.4"}, - {0x031604, "DISK Vol.5"}, - {0x031605, "DISK Vol.6"}, - {0x031606, "DISK Vol.7"}, - {0x031607, "DISK Vol.8"}, - {0x031608, "DISK Vol.9"}, - {0x031609, "DISK Vol.10"}, - {0x03160A, "DISK Vol.11"}, - {0x03160B, "DISK Vol.12"}, - {0x031700, "Hunters Report"}, - {0x031701, "Hunters Report (Rank A)"}, - {0x031702, "Hunters Report (Rank B)"}, - {0x031703, "Hunters Report (Rank C)"}, - {0x031704, "Hunters Report (Rank F)"}, - {0x031800, "Tablet"}, - {0x031802, "Dragon Scale"}, - {0x031803, "Heaven Striker Coat"}, - {0x031804, "Pioneer Parts"}, - {0x031805, "Amitie\'s Memo"}, - {0x031806, "Heart of Morolian"}, - {0x031807, "Rappy\'s Beak"}, - {0x031809, "D-Photon Core"}, - {0x03180A, "Liberta Kit"}, - {0x03180B, "Cell of MAG 0503"}, - {0x03180C, "Cell of MAG 0504"}, - {0x03180D, "Cell of MAG 0505"}, - {0x03180F, "Cell of MAG 0507"}, - {0x031900, "Team Points 500"}, - {0x031901, "Team Points 1000"}, - {0x031902, "Team Points 5000"}, - {0x031903, "Team Points 10000"}, + // Tools (03xxxx) + {0x030000, {"Monomate", false}}, + {0x030001, {"Dimate", false}}, + {0x030002, {"Trimate", false}}, + {0x030100, {"Monofluid", false}}, + {0x030101, {"Difluid", false}}, + {0x030102, {"Trifluid", false}}, + {0x030200, {"", false}}, // Special-cased in name_for_item + {0x030300, {"Sol Atomizer", false}}, + {0x030400, {"Moon Atomizer", false}}, + {0x030500, {"Star Atomizer", false}}, + {0x030600, {"Antidote", false}}, + {0x030601, {"Antiparalysis", false}}, + {0x030700, {"Telepipe", false}}, + {0x030800, {"Trap Vision", false}}, + {0x030900, {"Scape Doll", false}}, + {0x030A00, {"Monogrinder", false}}, + {0x030A01, {"Digrinder", false}}, + {0x030A02, {"Trigrinder", false}}, + {0x030B00, {"Power Material", false}}, + {0x030B01, {"Mind Material", false}}, + {0x030B02, {"Evade Material", false}}, + {0x030B03, {"HP Material", false}}, + {0x030B04, {"TP Material", false}}, + {0x030B05, {"Def Material", false}}, + {0x030B06, {"Luck Material", false}}, + {0x030C00, "Cell Of MAG 502"}, + {0x030C01, "Cell Of MAG 213"}, + {0x030C02, "Parts Of RoboChao"}, + {0x030C03, "Heart Of Opa Opa"}, + {0x030C04, "Heart Of Pian"}, + {0x030C05, "Heart Of Chao"}, + {0x030D00, "Sorcerer\'s Right Arm"}, + {0x030D01, "S-beat\'s Arms"}, + {0x030D02, "P-arm\'s Arms"}, + {0x030D03, "Delsaber\'s Right Arm"}, + {0x030D04, "C-bringer\'s Right Arm"}, + {0x030D05, "Delsaber\'s Left Arm"}, + {0x030D06, "S-red\'s Arms"}, + {0x030D07, "Dragon\'s Claw"}, + {0x030D08, "Hildebear\'s Head"}, + {0x030D09, "Hildeblue\'s Head"}, + {0x030D0A, "Parts of Baranz"}, + {0x030D0B, "Belra\'s Right Arm"}, + {0x030D0C, "Gi Gue\'s Body"}, + {0x030D0D, "Sinow Berill\'s Arms"}, + {0x030D0E, "G-Assassin\'s Arms"}, + {0x030D0F, "Booma\'s Right Arm"}, + {0x030D10, "Gobooma\'s Right Arm"}, + {0x030D11, "Gigobooma\'s Right Arm"}, + {0x030D12, "Gal Gryphon's Wing"}, + {0x030D13, "Rappy\'s Wing"}, + {0x030D14, "Cladding of Epsilon"}, + {0x030D15, "De Rol Le Shell"}, + {0x030E00, "Berill Photon"}, + {0x030E01, "Parasitic gene \"Flow\""}, + {0x030E02, "Magic stone \"Iritista\""}, + {0x030E03, "Blue-black stone"}, + {0x030E04, "Syncesta"}, + {0x030E05, "Magic Water"}, + {0x030E06, "Parasitic cell Type-D"}, + {0x030E07, "magic rock \"Heart Key\""}, + {0x030E08, "magic rock \"Moola\""}, + {0x030E09, "Star Amplifier"}, + {0x030E0A, "Book of HITOGATA"}, + {0x030E0B, "Heart of Chu Chu"}, + {0x030E0C, "Parts of EGG BLASTER"}, + {0x030E0D, "Heart of Angel"}, + {0x030E0E, "Heart of Devil"}, + {0x030E0F, "Kit of Hamburger"}, + {0x030E10, "Panther\'s Spirit"}, + {0x030E11, "Kit of MARK3"}, + {0x030E12, "Kit of MASTER SYSTEM"}, + {0x030E13, "Kit of GENESIS"}, + {0x030E14, "Kit of SEGA SATURN"}, + {0x030E15, "Kit of DREAMCAST"}, + {0x030E16, {"Amplifier of Resta", false}}, + {0x030E17, {"Amplifier of Anti", false}}, + {0x030E18, {"Amplifier of Shifta", false}}, + {0x030E19, {"Amplifier of Deband", false}}, + {0x030E1A, {"Amplifier of Foie", false}}, + {0x030E1B, {"Amplifier of Gifoie", false}}, + {0x030E1C, {"Amplifier of Rafoie", false}}, + {0x030E1D, {"Amplifier of Barta", false}}, + {0x030E1E, {"Amplifier of Gibarta", false}}, + {0x030E1F, {"Amplifier of Rabarta", false}}, + {0x030E20, {"Amplifier of Zonde", false}}, + {0x030E21, {"Amplifier of Gizonde", false}}, + {0x030E22, {"Amplifier of Razonde", false}}, + {0x030E23, {"Amplifier of Red", false}}, + {0x030E24, {"Amplifier of Blue", false}}, + {0x030E25, {"Amplifier of Yellow", false}}, + {0x030E26, "Heart of KAPU KAPU"}, + {0x030E27, "Photon Booster"}, + {0x030F00, "AddSlot"}, + {0x031000, "Photon Drop"}, + {0x031001, "Photon Sphere"}, + {0x031002, "Photon Crystal"}, + {0x031003, "Secret Lottery Ticket"}, + {0x031100, "Book of KATANA1"}, + {0x031101, "Book of KATANA2"}, + {0x031102, "Book of KATANA3"}, + {0x031200, "Weapons Bronze Badge"}, + {0x031201, "Weapons Silver Badge"}, + {0x031202, "Weapons Gold Badge"}, + {0x031203, "Weapons Crystal Badge"}, + {0x031204, "Weapons Steel Badge"}, + {0x031205, "Weapons Aluminum Badge"}, + {0x031206, "Weapons Leather Badge"}, + {0x031207, "Weapons Bone Badge"}, + {0x031208, "Letter of appreciation"}, + {0x031209, "Autograph Album"}, + {0x03120A, "Valentine\'s Chocolate"}, + {0x03120B, "New Year\'s Card"}, + {0x03120C, "Christmas Card"}, + {0x03120D, "Birthday Card"}, + {0x03120E, "Proof of Sonic Team"}, + {0x03120F, "Special Event Ticket"}, + {0x031210, "Flower Bouquet"}, + {0x031211, "Cake"}, + {0x031212, "Accessories"}, + {0x031213, "Mr.Naka\'s Business Card"}, + {0x031300, "Present"}, + {0x031400, "Chocolate"}, + {0x031401, "Candy"}, + {0x031402, "Cake"}, + {0x031403, "Silver Badge"}, + {0x031404, "Gold Badge"}, + {0x031405, "Crystal Badge"}, + {0x031406, "Iron Badge"}, + {0x031407, "Aluminum Badge"}, + {0x031408, "Leather Badge"}, + {0x031409, "Bone Badge"}, + {0x03140A, "Bouquet"}, + {0x03140B, "Decoction"}, + {0x031500, "Christmas Present"}, + {0x031501, "Easter Egg"}, + {0x031502, "Jack-O\'-Lantern"}, + {0x031600, "DISK Vol.1"}, + {0x031601, "DISK Vol.2"}, + {0x031602, "DISK Vol.3"}, + {0x031603, "DISK Vol.4"}, + {0x031604, "DISK Vol.5"}, + {0x031605, "DISK Vol.6"}, + {0x031606, "DISK Vol.7"}, + {0x031607, "DISK Vol.8"}, + {0x031608, "DISK Vol.9"}, + {0x031609, "DISK Vol.10"}, + {0x03160A, "DISK Vol.11"}, + {0x03160B, "DISK Vol.12"}, + {0x031700, "Hunters Report"}, + {0x031701, "Hunters Report (Rank A)"}, + {0x031702, "Hunters Report (Rank B)"}, + {0x031703, "Hunters Report (Rank C)"}, + {0x031704, "Hunters Report (Rank F)"}, + {0x031800, "Tablet"}, + {0x031802, "Dragon Scale"}, + {0x031803, "Heaven Striker Coat"}, + {0x031804, "Pioneer Parts"}, + {0x031805, "Amitie\'s Memo"}, + {0x031806, "Heart of Morolian"}, + {0x031807, "Rappy\'s Beak"}, + {0x031809, "D-Photon Core"}, + {0x03180A, "Liberta Kit"}, + {0x03180B, "Cell of MAG 0503"}, + {0x03180C, "Cell of MAG 0504"}, + {0x03180D, "Cell of MAG 0505"}, + {0x03180F, "Cell of MAG 0507"}, + {0x031900, "Team Points 500"}, + {0x031901, "Team Points 1000"}, + {0x031902, "Team Points 5000"}, + {0x031903, "Team Points 10000"}, }); string ItemData::name(bool include_color_codes) const { @@ -1319,14 +1308,14 @@ string ItemData::name(bool include_color_codes) const { if (this->is_s_rank_weapon() && (this->data1[6] & 0x18)) { // S-rank (has name instead of percent bonuses) uint8_t char_indexes[8] = { - static_cast((this->data1w[3] >> 5) & 0x1F), - static_cast(this->data1w[3] & 0x1F), - static_cast((this->data1w[4] >> 10) & 0x1F), - static_cast((this->data1w[4] >> 5) & 0x1F), - static_cast(this->data1w[4] & 0x1F), - static_cast((this->data1w[5] >> 10) & 0x1F), - static_cast((this->data1w[5] >> 5) & 0x1F), - static_cast(this->data1w[5] & 0x1F), + static_cast((this->data1w[3] >> 5) & 0x1F), + static_cast(this->data1w[3] & 0x1F), + static_cast((this->data1w[4] >> 10) & 0x1F), + static_cast((this->data1w[4] >> 5) & 0x1F), + static_cast(this->data1w[4] & 0x1F), + static_cast((this->data1w[5] >> 10) & 0x1F), + static_cast((this->data1w[5] >> 5) & 0x1F), + static_cast(this->data1w[5] & 0x1F), }; const char* translation_table = "\0ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; @@ -1360,7 +1349,7 @@ string ItemData::name(bool include_color_codes) const { percentages[0], percentages[1], percentages[2], percentages[3], percentages[4])); } - // For armors, add the slots, unit modifiers, and/or DEF/EVP bonuses + // For armors, add the slots, unit modifiers, and/or DEF/EVP bonuses } else if (this->data1[0] == 0x01) { if (this->data1[1] == 0x03) { // Units uint16_t modifier = (this->data1[8] << 8) | this->data1[7]; @@ -1394,7 +1383,7 @@ string ItemData::name(bool include_color_codes) const { } } - // For mags, add tons of info + // For mags, add tons of info } else if (this->data1[0] == 0x02) { ret_tokens.emplace_back(string_printf("LV%hhu", this->data1[2])); @@ -1458,25 +1447,25 @@ string ItemData::name(bool include_color_codes) const { ret_tokens.emplace_back(move(token)); static const vector mag_colors({ - /* 00 */ "red", - /* 01 */ "blue", - /* 02 */ "yellow", - /* 03 */ "green", - /* 04 */ "purple", - /* 05 */ "black", - /* 06 */ "white", - /* 07 */ "cyan", - /* 08 */ "brown", - /* 09 */ "orange", - /* 0A */ "light blue", - /* 0B */ "olive", - /* 0C */ "light cyan", - /* 0D */ "dark purple", - /* 0E */ "grey", - /* 0F */ "light grey", - /* 10 */ "pink", - /* 11 */ "dark cyan", - /* 12 */ "costume color", + /* 00 */ "red", + /* 01 */ "blue", + /* 02 */ "yellow", + /* 03 */ "green", + /* 04 */ "purple", + /* 05 */ "black", + /* 06 */ "white", + /* 07 */ "cyan", + /* 08 */ "brown", + /* 09 */ "orange", + /* 0A */ "light blue", + /* 0B */ "olive", + /* 0C */ "light cyan", + /* 0D */ "dark purple", + /* 0E */ "grey", + /* 0F */ "light grey", + /* 10 */ "pink", + /* 11 */ "dark cyan", + /* 12 */ "costume color", }); try { ret_tokens.emplace_back(string_printf("(%s)", mag_colors.at(this->data2[0]))); @@ -1485,7 +1474,7 @@ string ItemData::name(bool include_color_codes) const { } } - // For tools, add the amount (if applicable) + // For tools, add the amount (if applicable) } else if (this->data1[0] == 0x03) { if (this->max_stack_size() > 1) { ret_tokens.emplace_back(string_printf("x%hhu", this->data1[5])); diff --git a/src/ItemData.hh b/src/ItemData.hh index 1e9ffe35..d6f6598a 100644 --- a/src/ItemData.hh +++ b/src/ItemData.hh @@ -1,12 +1,10 @@ #pragma once -#include #include +#include #include "Text.hh" - - constexpr uint32_t MESETA_IDENTIFIER = 0x00040000; struct ItemMagStats { @@ -21,15 +19,15 @@ struct ItemMagStats { uint8_t color; ItemMagStats() - : iq(0), - synchro(40), - def(500), - pow(0), - dex(0), - mind(0), - flags(0), - photon_blasts(0), - color(14) { } + : iq(0), + synchro(40), + def(500), + pow(0), + dex(0), + mind(0), + flags(0), + photon_blasts(0), + color(14) {} inline uint16_t def_level() const { return this->def / 100; diff --git a/src/ItemParameterTable.cc b/src/ItemParameterTable.cc index f4e4611d..4f1f9c21 100644 --- a/src/ItemParameterTable.cc +++ b/src/ItemParameterTable.cc @@ -2,10 +2,8 @@ using namespace std; - - ItemParameterTable::ItemParameterTable(shared_ptr data) - : data(data), r(*data) { + : data(data), r(*data) { size_t offset_table_offset = this->r.pget_u32l(this->data->size() - 0x10); this->offsets = &r.pget(offset_table_offset); } @@ -139,8 +137,6 @@ uint8_t ItemParameterTable::get_max_tech_level(uint8_t char_class, uint8_t tech_ return r.pget_u8(this->offsets->max_tech_level_table + tech_num * 12 + char_class); } - - const ItemParameterTable::ItemBase& ItemParameterTable::get_item_definition( const ItemData& item) const { switch (item.data1[0]) { @@ -176,8 +172,8 @@ uint8_t ItemParameterTable::get_item_base_stars(const ItemData& item) const { return this->get_item_stars(this->get_item_definition(item).id); } else if (item.data1[0] == 3) { const auto& def = (item.data1[1] == 2) - ? this->get_tool(2, item.data1[4]) - : this->get_tool(item.data1[1], item.data1[2]); + ? this->get_tool(2, item.data1[4]) + : this->get_tool(item.data1[1], item.data1[2]); return (def.item_flag & 0x80) ? 12 : 0; } else { return 0; @@ -225,8 +221,6 @@ bool ItemParameterTable::is_unsealable_item(const ItemData& item) const { return false; } - - size_t ItemParameterTable::price_for_item(const ItemData& item) const { switch (item.data1[0]) { case 0: { @@ -281,10 +275,9 @@ size_t ItemParameterTable::price_for_item(const ItemData& item) const { const auto& def = this->get_armor_or_shield(item.data1[1], item.data1[2]); double power_factor = def.dfp + def.evp + def_bonus + evp_bonus; double power_factor_floor = static_cast((power_factor * power_factor) / sale_divisor); - return power_factor_floor + ( - 70.0 * - static_cast(item.data1[5] + 1) * - static_cast(def.required_level + 1)); + return power_factor_floor + (70.0 * + static_cast(item.data1[5] + 1) * + static_cast(def.required_level + 1)); } case 2: diff --git a/src/ItemParameterTable.hh b/src/ItemParameterTable.hh index e1d76316..6b1c6b54 100644 --- a/src/ItemParameterTable.hh +++ b/src/ItemParameterTable.hh @@ -3,13 +3,11 @@ #include #include -#include #include +#include -#include "Text.hh" #include "ItemData.hh" - - +#include "Text.hh" class ItemParameterTable { public: diff --git a/src/Items.cc b/src/Items.cc index 79824cbd..5e929ef6 100644 --- a/src/Items.cc +++ b/src/Items.cc @@ -6,9 +6,7 @@ using namespace std; - - -/* these items all need some kind of special handling that hasn't been implemented yet. +/* These items all need some kind of special handling that hasn't been implemented yet. 030B04 = TP Material (?) 030C00 = Cell Of MAG 502 @@ -167,7 +165,7 @@ void player_use_item(shared_ptr c, size_t item_index) { // used item. On GC and later versions, this does not happen, so we should // delete the item here. bool should_delete_item = (c->version() != GameVersion::DC) && - (c->version() != GameVersion::PC); + (c->version() != GameVersion::PC); auto& item = c->game_data.player()->inventory.items[item_index]; if (item.data.data1w[0] == 0x0203) { // technique disk diff --git a/src/Items.hh b/src/Items.hh index 57b7e9d6..d053ab87 100644 --- a/src/Items.hh +++ b/src/Items.hh @@ -8,6 +8,4 @@ #include "Client.hh" #include "StaticGameData.hh" - - void player_use_item(std::shared_ptr c, size_t item_index); diff --git a/src/LevelTable.cc b/src/LevelTable.cc index 3547571f..2399b886 100644 --- a/src/LevelTable.cc +++ b/src/LevelTable.cc @@ -8,8 +8,6 @@ using namespace std; - - LevelTable::LevelTable(shared_ptr data, bool compressed) { if (compressed) { this->data.reset(new string(prs_decompress(*data))); @@ -30,8 +28,8 @@ const PlayerStats& LevelTable::base_stats_for_class(uint8_t char_class) const { return this->table->base_stats[char_class]; } -const LevelTable::LevelStats& LevelTable::stats_for_level(uint8_t char_class, - uint8_t level) const { +const LevelTable::LevelStats& LevelTable::stats_for_level( + uint8_t char_class, uint8_t level) const { if (char_class >= 12) { throw invalid_argument("invalid character class"); } diff --git a/src/LevelTable.hh b/src/LevelTable.hh index f4664c1c..19862c9e 100644 --- a/src/LevelTable.hh +++ b/src/LevelTable.hh @@ -3,10 +3,8 @@ #include #include -#include #include - - +#include struct PlayerStats { le_uint16_t atp; diff --git a/src/License.cc b/src/License.cc index 8ef5d790..613cdf76 100644 --- a/src/License.cc +++ b/src/License.cc @@ -5,14 +5,12 @@ #include #include -#include "Loggers.hh" #include "License.hh" +#include "Loggers.hh" using namespace std; - - -License::License() : serial_number(0), privileges(0), ban_end_time(0) { } +License::License() : serial_number(0), privileges(0), ban_end_time(0) {} string License::str() const { string ret = string_printf("License(serial_number=%" PRIu32, this->serial_number); @@ -39,12 +37,10 @@ string License::str() const { return ret + ")"; } - - -LicenseManager::LicenseManager() : filename(""), autosave(false) { } +LicenseManager::LicenseManager() : filename(""), autosave(false) {} LicenseManager::LicenseManager(const string& filename) - : filename(filename), autosave(true) { + : filename(filename), autosave(true) { try { auto licenses = load_vector_file(this->filename); for (const auto& read_license : licenses) { @@ -62,7 +58,7 @@ LicenseManager::LicenseManager(const string& filename) } catch (const cannot_open_file&) { license_log.warning("File %s does not exist; no licenses are registered", - this->filename.c_str()); + this->filename.c_str()); } } @@ -84,7 +80,7 @@ void LicenseManager::set_autosave(bool autosave) { } shared_ptr LicenseManager::verify_pc(uint32_t serial_number, - const string& access_key) const { + const string& access_key) const { try { auto& license = this->serial_number_to_license.at(serial_number); if (!license->access_key.eq_n(access_key, 8)) { @@ -101,7 +97,7 @@ shared_ptr LicenseManager::verify_pc(uint32_t serial_number, } shared_ptr LicenseManager::verify_gc(uint32_t serial_number, - const string& access_key) const { + const string& access_key) const { try { auto& license = this->serial_number_to_license.at(serial_number); if (!license->access_key.eq_n(access_key, 12)) { @@ -117,7 +113,7 @@ shared_ptr LicenseManager::verify_gc(uint32_t serial_number, } shared_ptr LicenseManager::verify_gc(uint32_t serial_number, - const string& access_key, const string& password) const { + const string& access_key, const string& password) const { try { auto& license = this->serial_number_to_license.at(serial_number); if (!license->access_key.eq_n(access_key, 12)) { @@ -136,7 +132,7 @@ shared_ptr LicenseManager::verify_gc(uint32_t serial_number, } shared_ptr LicenseManager::verify_bb(const string& username, - const string& password) const { + const string& password) const { try { auto& license = this->bb_username_to_license.at(username); if (license->bb_password != password) { @@ -200,8 +196,6 @@ vector LicenseManager::snapshot() const { return ret; } - - shared_ptr LicenseManager::create_license_pc( uint32_t serial_number, const string& access_key, bool temporary) { shared_ptr l(new License()); diff --git a/src/License.hh b/src/License.hh index 838e2c78..066f3403 100644 --- a/src/License.hh +++ b/src/License.hh @@ -1,29 +1,29 @@ #pragma once -#include -#include -#include #include +#include +#include +#include #include "Text.hh" enum Privilege { - KICK_USER = 0x00000001, - BAN_USER = 0x00000002, - SILENCE_USER = 0x00000004, + KICK_USER = 0x00000001, + BAN_USER = 0x00000002, + SILENCE_USER = 0x00000004, CHANGE_LOBBY_INFO = 0x00000008, - CHANGE_EVENT = 0x00000010, - ANNOUNCE = 0x00000020, - FREE_JOIN_GAMES = 0x00000040, - UNLOCK_GAMES = 0x00000080, + CHANGE_EVENT = 0x00000010, + ANNOUNCE = 0x00000020, + FREE_JOIN_GAMES = 0x00000040, + UNLOCK_GAMES = 0x00000080, - DEBUG = 0x01000000, + DEBUG = 0x01000000, - MODERATOR = 0x00000007, - ADMINISTRATOR = 0x0000003F, - ROOT = 0x7FFFFFFF, + MODERATOR = 0x00000007, + ADMINISTRATOR = 0x0000003F, + ROOT = 0x7FFFFFFF, - TEMPORARY = 0x80000000, + TEMPORARY = 0x80000000, }; enum LicenseVerifyAction { @@ -48,17 +48,17 @@ struct License { class incorrect_password : public std::invalid_argument { public: - incorrect_password() : invalid_argument("incorrect password") { } + incorrect_password() : invalid_argument("incorrect password") {} }; class incorrect_access_key : public std::invalid_argument { public: - incorrect_access_key() : invalid_argument("incorrect access key") { } + incorrect_access_key() : invalid_argument("incorrect access key") {} }; class missing_license : public std::invalid_argument { public: - missing_license() : invalid_argument("missing license") { } + missing_license() : invalid_argument("missing license") {} }; class LicenseManager { diff --git a/src/Lobby.cc b/src/Lobby.cc index 9ad6dc91..d1e2f7ea 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -10,27 +10,25 @@ using namespace std; - - Lobby::Lobby(uint32_t id) - : log(string_printf("[Lobby/%" PRIX32 "] ", id), lobby_log.min_level), - lobby_id(id), - min_level(0), - max_level(0xFFFFFFFF), - next_game_item_id(0x00810000), - version(GameVersion::GC), - section_id(0), - episode(Episode::NONE), - mode(GameMode::NORMAL), - difficulty(0), - random_seed(random_object()), - random(new mt19937(this->random_seed)), - event(0), - block(0), - type(0), - leader_id(0), - max_clients(12), - flags(0) { + : log(string_printf("[Lobby/%" PRIX32 "] ", id), lobby_log.min_level), + lobby_id(id), + min_level(0), + max_level(0xFFFFFFFF), + next_game_item_id(0x00810000), + version(GameVersion::GC), + section_id(0), + episode(Episode::NONE), + mode(GameMode::NORMAL), + difficulty(0), + random_seed(random_object()), + random(new mt19937(this->random_seed)), + event(0), + block(0), + type(0), + leader_id(0), + max_clients(12), + flags(0) { for (size_t x = 0; x < 12; x++) { this->next_item_id[x] = 0x00010000 + 0x00200000 * x; } @@ -135,7 +133,8 @@ void Lobby::add_client(shared_ptr c, ssize_t required_client_id) { lobby_data.player_tag = 0x00010000; lobby_data.guild_card = c->license->serial_number; lobby_data.name = encode_sjis(c->game_data.player()->disp.name); - this->battle_record->add_player(lobby_data, + this->battle_record->add_player( + lobby_data, c->game_data.player()->inventory, c->game_data.player()->disp.to_dcpcv3()); } @@ -215,10 +214,8 @@ void Lobby::move_client_to_lobby( dest_lobby->add_client(c, required_client_id); } - - shared_ptr Lobby::find_client(const u16string* identifier, - uint64_t serial_number) { + uint64_t serial_number) { for (size_t x = 0; x < this->max_clients; x++) { if (!this->clients[x]) { continue; @@ -235,8 +232,6 @@ shared_ptr Lobby::find_client(const u16string* identifier, throw out_of_range("client not found"); } - - uint8_t Lobby::game_event_for_lobby_event(uint8_t lobby_event) { if (lobby_event > 7) { return 0; @@ -250,8 +245,6 @@ uint8_t Lobby::game_event_for_lobby_event(uint8_t lobby_event) { return lobby_event; } - - void Lobby::add_item(const PlayerInventoryItem& item, uint8_t area, float x, float z) { auto& fi = this->item_id_to_floor_item[item.data.id]; fi.inv_item = item; diff --git a/src/Lobby.hh b/src/Lobby.hh index f4fc54bb..24daac0a 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -2,13 +2,13 @@ #include -#include #include -#include -#include #include -#include #include +#include +#include +#include +#include #include "Client.hh" #include "Episode3/BattleRecord.hh" @@ -21,27 +21,25 @@ #include "StaticGameData.hh" #include "Text.hh" - - struct Lobby : public std::enable_shared_from_this { enum Flag { - GAME = 0x00000001, - NON_V1_ONLY = 0x00000002, // DC NTE and DCv1 not allowed - PERSISTENT = 0x00000004, + GAME = 0x00000001, + NON_V1_ONLY = 0x00000002, // DC NTE and DCv1 not allowed + PERSISTENT = 0x00000004, // Flags used only for games - CHEATS_ENABLED = 0x00000100, - QUEST_IN_PROGRESS = 0x00000200, - BATTLE_IN_PROGRESS = 0x00000400, - JOINABLE_QUEST_IN_PROGRESS = 0x00000800, - ITEM_TRACKING_ENABLED = 0x00001000, - IS_SPECTATOR_TEAM = 0x00002000, // episode must be EP3 also - SPECTATORS_FORBIDDEN = 0x00004000, + CHEATS_ENABLED = 0x00000100, + QUEST_IN_PROGRESS = 0x00000200, + BATTLE_IN_PROGRESS = 0x00000400, + JOINABLE_QUEST_IN_PROGRESS = 0x00000800, + ITEM_TRACKING_ENABLED = 0x00001000, + IS_SPECTATOR_TEAM = 0x00002000, // episode must be EP3 also + SPECTATORS_FORBIDDEN = 0x00004000, START_BATTLE_PLAYER_IMMEDIATELY = 0x00008000, // Flags used only for lobbies - PUBLIC = 0x01000000, - DEFAULT = 0x02000000, + PUBLIC = 0x01000000, + DEFAULT = 0x02000000, }; PrefixedLogger log; diff --git a/src/Loggers.cc b/src/Loggers.cc index 327e8f98..fbf050a2 100644 --- a/src/Loggers.cc +++ b/src/Loggers.cc @@ -4,32 +4,30 @@ using namespace std; - - -PrefixedLogger ax_messages_log ("[$ax message] " , LogLevel::USE_DEFAULT); -PrefixedLogger channel_exceptions_log("[Channel] " , LogLevel::USE_DEFAULT); -PrefixedLogger client_log ("" , LogLevel::USE_DEFAULT); -PrefixedLogger command_data_log ("[Commands] " , LogLevel::USE_DEFAULT); -PrefixedLogger config_log ("[Config] " , LogLevel::USE_DEFAULT); -PrefixedLogger dns_server_log ("[DNSServer] " , LogLevel::USE_DEFAULT); -PrefixedLogger function_compiler_log ("[FunctionCompiler] ", LogLevel::USE_DEFAULT); +PrefixedLogger ax_messages_log("[$ax message] ", LogLevel::USE_DEFAULT); +PrefixedLogger channel_exceptions_log("[Channel] ", LogLevel::USE_DEFAULT); +PrefixedLogger client_log("", LogLevel::USE_DEFAULT); +PrefixedLogger command_data_log("[Commands] ", LogLevel::USE_DEFAULT); +PrefixedLogger config_log("[Config] ", LogLevel::USE_DEFAULT); +PrefixedLogger dns_server_log("[DNSServer] ", LogLevel::USE_DEFAULT); +PrefixedLogger function_compiler_log("[FunctionCompiler] ", LogLevel::USE_DEFAULT); PrefixedLogger ip_stack_simulator_log("[IPStackSimulator] ", LogLevel::USE_DEFAULT); -PrefixedLogger license_log ("[LicenseManager] " , LogLevel::USE_DEFAULT); -PrefixedLogger lobby_log ("" , LogLevel::USE_DEFAULT); -PrefixedLogger patch_index_log ("[PatchFileIndex] " , LogLevel::USE_DEFAULT); -PrefixedLogger player_data_log ("" , LogLevel::USE_DEFAULT); -PrefixedLogger proxy_server_log ("[ProxyServer] " , LogLevel::USE_DEFAULT); -PrefixedLogger replay_log ("[ReplaySession] " , LogLevel::USE_DEFAULT); -PrefixedLogger server_log ("[Server] " , LogLevel::USE_DEFAULT); -PrefixedLogger static_game_data_log ("[StaticGameData] " , LogLevel::USE_DEFAULT); +PrefixedLogger license_log("[LicenseManager] ", LogLevel::USE_DEFAULT); +PrefixedLogger lobby_log("", LogLevel::USE_DEFAULT); +PrefixedLogger patch_index_log("[PatchFileIndex] ", LogLevel::USE_DEFAULT); +PrefixedLogger player_data_log("", LogLevel::USE_DEFAULT); +PrefixedLogger proxy_server_log("[ProxyServer] ", LogLevel::USE_DEFAULT); +PrefixedLogger replay_log("[ReplaySession] ", LogLevel::USE_DEFAULT); +PrefixedLogger server_log("[Server] ", LogLevel::USE_DEFAULT); +PrefixedLogger static_game_data_log("[StaticGameData] ", LogLevel::USE_DEFAULT); static LogLevel log_level_for_name(const string& name) { static const unordered_map levels({ - {"debug", LogLevel::DEBUG}, - {"info", LogLevel::INFO}, - {"warning", LogLevel::WARNING}, - {"error", LogLevel::ERROR}, - {"disabled", LogLevel::DISABLED}, + {"debug", LogLevel::DEBUG}, + {"info", LogLevel::INFO}, + {"warning", LogLevel::WARNING}, + {"error", LogLevel::ERROR}, + {"disabled", LogLevel::DISABLED}, }); return levels.at(tolower(name)); } @@ -38,24 +36,25 @@ static void set_log_level_from_json( PrefixedLogger& log, shared_ptr d, const char* json_key) { try { log.min_level = log_level_for_name(d->at(json_key)->as_string()); - } catch (const JSONObject::key_error&) { } + } catch (const JSONObject::key_error&) { + } } void set_log_levels_from_json(shared_ptr json) { - set_log_level_from_json(ax_messages_log , json, "AXMessages"); + set_log_level_from_json(ax_messages_log, json, "AXMessages"); set_log_level_from_json(channel_exceptions_log, json, "ChannelExceptions"); - set_log_level_from_json(client_log , json, "Clients"); - set_log_level_from_json(command_data_log , json, "CommandData"); - set_log_level_from_json(config_log , json, "Config"); - set_log_level_from_json(dns_server_log , json, "DNSServer"); - set_log_level_from_json(function_compiler_log , json, "FunctionCompiler"); + set_log_level_from_json(client_log, json, "Clients"); + set_log_level_from_json(command_data_log, json, "CommandData"); + set_log_level_from_json(config_log, json, "Config"); + set_log_level_from_json(dns_server_log, json, "DNSServer"); + set_log_level_from_json(function_compiler_log, json, "FunctionCompiler"); set_log_level_from_json(ip_stack_simulator_log, json, "IPStackSimulator"); - set_log_level_from_json(license_log , json, "LicenseManager"); - set_log_level_from_json(lobby_log , json, "Lobbies"); - set_log_level_from_json(patch_index_log , json, "PatchFileIndex"); - set_log_level_from_json(player_data_log , json, "PlayerData"); - set_log_level_from_json(proxy_server_log , json, "ProxyServer"); - set_log_level_from_json(replay_log , json, "Replay"); - set_log_level_from_json(server_log , json, "GameServer"); - set_log_level_from_json(static_game_data_log , json, "StaticGameData"); + set_log_level_from_json(license_log, json, "LicenseManager"); + set_log_level_from_json(lobby_log, json, "Lobbies"); + set_log_level_from_json(patch_index_log, json, "PatchFileIndex"); + set_log_level_from_json(player_data_log, json, "PlayerData"); + set_log_level_from_json(proxy_server_log, json, "ProxyServer"); + set_log_level_from_json(replay_log, json, "Replay"); + set_log_level_from_json(server_log, json, "GameServer"); + set_log_level_from_json(static_game_data_log, json, "StaticGameData"); } diff --git a/src/Loggers.hh b/src/Loggers.hh index d8745c62..6a86b95c 100644 --- a/src/Loggers.hh +++ b/src/Loggers.hh @@ -1,9 +1,7 @@ #pragma once -#include #include - - +#include extern PrefixedLogger ax_messages_log; extern PrefixedLogger channel_exceptions_log; diff --git a/src/Main.cc b/src/Main.cc index 97b976ca..5759e48d 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include #include @@ -21,9 +21,9 @@ #include "IPStackSimulator.hh" #include "Loggers.hh" #include "NetworkAddresses.hh" +#include "PSOGCObjectGraph.hh" #include "Product.hh" #include "ProxyServer.hh" -#include "PSOGCObjectGraph.hh" #include "ReplaySession.hh" #include "SaveFileFormats.hh" #include "SendCommands.hh" @@ -35,12 +35,8 @@ using namespace std; - - bool use_terminal_colors = false; - - template vector parse_int_vector(shared_ptr o) { vector ret; @@ -50,8 +46,6 @@ vector parse_int_vector(shared_ptr o) { return ret; } - - void drop_privileges(const string& username) { if ((getuid() != 0) || (getgid() != 0)) { throw runtime_error(string_printf( @@ -76,11 +70,9 @@ void drop_privileges(const string& username) { throw runtime_error(string_printf("can\'t switch to user %d (%s)", pw->pw_uid, error.c_str())); } - config_log.info("Switched to user %s (%d:%d)", username.c_str(), pw->pw_uid, pw->pw_gid); + config_log.info("Switched to user %s (%d:%d)", username.c_str(), pw->pw_uid, pw->pw_gid); } - - void print_usage() { fputs("\ Usage:\n\ @@ -191,7 +183,8 @@ A few options apply to multiple modes described above:\n\ a hex string before encrypting/decoding/etc.\n\ --config=FILENAME\n\ Use this file instead of system/config.json.\n\ -", stderr); +", + stderr); } enum class Behavior { @@ -219,45 +212,47 @@ enum class Behavior { REPLAY_LOG, CAT_CLIENT, GENERATE_PRODUCT, + INSPECT_PRODUCT, PRODUCT_SPEED_TEST, }; static bool behavior_takes_input_filename(Behavior b) { return (b == Behavior::COMPRESS_PRS) || - (b == Behavior::DECOMPRESS_PRS) || - (b == Behavior::COMPRESS_BC0) || - (b == Behavior::DECOMPRESS_BC0) || - (b == Behavior::PRS_SIZE) || - (b == Behavior::PRS_DISASSEMBLE) || - (b == Behavior::ENCRYPT_DATA) || - (b == Behavior::DECRYPT_DATA) || - (b == Behavior::DECRYPT_TRIVIAL_DATA) || - (b == Behavior::DECRYPT_GCI_SAVE) || - (b == Behavior::ENCRYPT_GCI_SAVE) || - (b == Behavior::DECODE_QUEST_FILE) || - (b == Behavior::DECODE_SJIS) || - (b == Behavior::FORMAT_ITEMRT_ENTRY) || - (b == Behavior::FORMAT_ITEMRT_REL) || - (b == Behavior::EXTRACT_GSL) || - (b == Behavior::EXTRACT_BML) || - (b == Behavior::PARSE_OBJECT_GRAPH) || - (b == Behavior::REPLAY_LOG) || - (b == Behavior::CAT_CLIENT); + (b == Behavior::DECOMPRESS_PRS) || + (b == Behavior::COMPRESS_BC0) || + (b == Behavior::DECOMPRESS_BC0) || + (b == Behavior::PRS_SIZE) || + (b == Behavior::PRS_DISASSEMBLE) || + (b == Behavior::ENCRYPT_DATA) || + (b == Behavior::DECRYPT_DATA) || + (b == Behavior::DECRYPT_TRIVIAL_DATA) || + (b == Behavior::DECRYPT_GCI_SAVE) || + (b == Behavior::ENCRYPT_GCI_SAVE) || + (b == Behavior::DECODE_QUEST_FILE) || + (b == Behavior::DECODE_SJIS) || + (b == Behavior::FORMAT_ITEMRT_ENTRY) || + (b == Behavior::FORMAT_ITEMRT_REL) || + (b == Behavior::EXTRACT_GSL) || + (b == Behavior::EXTRACT_BML) || + (b == Behavior::PARSE_OBJECT_GRAPH) || + (b == Behavior::REPLAY_LOG) || + (b == Behavior::CAT_CLIENT) || + (b == Behavior::INSPECT_PRODUCT); } static bool behavior_takes_output_filename(Behavior b) { return (b == Behavior::COMPRESS_PRS) || - (b == Behavior::DECOMPRESS_PRS) || - (b == Behavior::COMPRESS_BC0) || - (b == Behavior::DECOMPRESS_BC0) || - (b == Behavior::ENCRYPT_DATA) || - (b == Behavior::DECRYPT_DATA) || - (b == Behavior::DECRYPT_TRIVIAL_DATA) || - (b == Behavior::DECRYPT_GCI_SAVE) || - (b == Behavior::ENCRYPT_GCI_SAVE) || - (b == Behavior::DECODE_SJIS) || - (b == Behavior::EXTRACT_GSL) || - (b == Behavior::EXTRACT_BML); + (b == Behavior::DECOMPRESS_PRS) || + (b == Behavior::COMPRESS_BC0) || + (b == Behavior::DECOMPRESS_BC0) || + (b == Behavior::ENCRYPT_DATA) || + (b == Behavior::DECRYPT_DATA) || + (b == Behavior::DECRYPT_TRIVIAL_DATA) || + (b == Behavior::DECRYPT_GCI_SAVE) || + (b == Behavior::ENCRYPT_GCI_SAVE) || + (b == Behavior::DECODE_SJIS) || + (b == Behavior::EXTRACT_GSL) || + (b == Behavior::EXTRACT_BML); } enum class QuestFileFormat { @@ -344,7 +339,8 @@ int main(int argc, char** argv) { if (!strcmp(argv[x], "help")) { print_usage(); return 0; - } if (!strcmp(argv[x], "compress-prs")) { + } + if (!strcmp(argv[x], "compress-prs")) { behavior = Behavior::COMPRESS_PRS; } else if (!strcmp(argv[x], "decompress-prs")) { behavior = Behavior::DECOMPRESS_PRS; @@ -400,6 +396,8 @@ int main(int argc, char** argv) { behavior = Behavior::EXTRACT_BML; } else if (!strcmp(argv[x], "generate-product")) { behavior = Behavior::GENERATE_PRODUCT; + } else if (!strcmp(argv[x], "inspect-product")) { + behavior = Behavior::INSPECT_PRODUCT; } else if (!strcmp(argv[x], "product-speed-test")) { behavior = Behavior::PRODUCT_SPEED_TEST; } else { @@ -435,9 +433,9 @@ int main(int argc, char** argv) { // If the output is to a specified file, write it there if (output_filename && strcmp(output_filename, "-")) { save_file(output_filename, data, size); - // If no output filename is given and an input filename is given, write to - // .dec (or an appropriate extension, if it can be - // autodetected) + // If no output filename is given and an input filename is given, write to + // .dec (or an appropriate extension, if it can be + // autodetected) } else if (!output_filename && input_filename && strcmp(input_filename, "-")) { string filename = input_filename; if (behavior == Behavior::COMPRESS_PRS) { @@ -472,11 +470,11 @@ int main(int argc, char** argv) { filename += ".dec"; } save_file(filename, data, size); - // If stdout is a terminal, use print_data to write the result + // If stdout is a terminal, use print_data to write the result } else if (isatty(fileno(stdout))) { print_data(stdout, data, size); fflush(stdout); - // If stdout is not a terminal, write the data as-is + // If stdout is not a terminal, write the data as-is } else { fwritex(stdout, data, size); fflush(stdout); @@ -756,7 +754,8 @@ int main(int argc, char** argv) { } } return false; - }, 0, 0x100000000, num_threads); + }, + 0, 0x100000000, num_threads); if (seed < 0x100000000) { log_info("Found seed %08" PRIX64, seed); @@ -774,15 +773,15 @@ int main(int argc, char** argv) { string output_filename_base = input_filename; if (quest_file_type == QuestFileFormat::GCI) { int64_t dec_seed = seed.empty() ? -1 : stoul(seed, nullptr, 16); - save_file(output_filename_base + ".dec", Quest::decode_gci( - input_filename, num_threads, dec_seed)); + auto decoded = Quest::decode_gci(input_filename, num_threads, dec_seed); + save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::VMS) { int64_t dec_seed = seed.empty() ? -1 : stoul(seed, nullptr, 16); - save_file(output_filename_base + ".dec", Quest::decode_vms( - input_filename, num_threads, dec_seed)); + auto decoded = Quest::decode_vms(input_filename, num_threads, dec_seed); + save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::DLQ) { - save_file(output_filename_base + ".dec", Quest::decode_dlq( - input_filename)); + auto decoded = Quest::decode_dlq(input_filename); + save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::QST) { auto data = Quest::decode_qst(input_filename); save_file(output_filename_base + ".bin", data.first); @@ -874,7 +873,8 @@ int main(int argc, char** argv) { uint32_t expanded_probability = RareItemSet::expand_rate(r.probability); auto frac = reduce_fraction(expanded_probability, 0x100000000); - return string_printf("(%02hhX => %08" PRIX32 " => %" PRIu64 "/%" PRIu64 ") %02hhX%02hhX%02hhX (%s)", + return string_printf( + "(%02hhX => %08" PRIX32 " => %" PRIu64 "/%" PRIu64 ") %02hhX%02hhX%02hhX (%s)", r.probability, expanded_probability, frac.first, frac.second, r.item_code[0], r.item_code[1], r.item_code[2], name.c_str()); }; @@ -913,7 +913,8 @@ int main(int argc, char** argv) { uint32_t expanded_probability = RareItemSet::expand_rate(r.probability); auto frac = reduce_fraction(expanded_probability, 0x100000000); - return string_printf("(%02hhX => %08" PRIX32 " => %" PRIu64 "/%" PRIu64 ") %02hhX%02hhX%02hhX (%s)", + return string_printf( + "(%02hhX => %08" PRIX32 " => %" PRIu64 "/%" PRIu64 ") %02hhX%02hhX%02hhX (%s)", r.probability, expanded_probability, frac.first, frac.second, r.item_code[0], r.item_code[1], r.item_code[2], name.c_str()); }; @@ -949,9 +950,9 @@ int main(int argc, char** argv) { }; static const vector episodes = { - Episode::EP1, - Episode::EP2, - Episode::EP4, + Episode::EP1, + Episode::EP2, + Episode::EP4, }; for (Episode episode : episodes) { for (uint8_t difficulty = 0; difficulty < 4; difficulty++) { @@ -1006,7 +1007,26 @@ int main(int argc, char** argv) { case Behavior::GENERATE_PRODUCT: { auto product = generate_product(domain, subdomain); - fprintf(stderr, "%s\n", product.c_str()); + fprintf(stdout, "%s\n", product.c_str()); + break; + } + + case Behavior::INSPECT_PRODUCT: { + if (!input_filename) { + throw invalid_argument("no product given"); + } + size_t num_valid_subdomains = 0; + for (uint8_t domain = 0; domain < 3; domain++) { + for (uint8_t subdomain = 0; subdomain < 3; subdomain++) { + if (product_is_valid_fast(input_filename, domain, subdomain)) { + fprintf(stdout, "%s is valid in domain %hhu subdomain %hhu\n", input_filename, domain, subdomain); + num_valid_subdomains++; + } + } + } + if (num_valid_subdomains == 0) { + fprintf(stdout, "%s is not valid in any domain\n", input_filename); + } break; } @@ -1049,7 +1069,8 @@ int main(int argc, char** argv) { config_log.info("Starting game server"); state->game_server.reset(new Server(base, state)); - shared_ptr log_f(stdin, +[](FILE*) { }); + shared_ptr log_f( + stdin, +[](FILE*) {}); if (input_filename && strcmp(input_filename, "-")) { log_f = fopen_shared(input_filename, "rt"); } @@ -1074,14 +1095,14 @@ int main(int argc, char** argv) { // destination is supported, and we have to manually specify the // destination netloc here. if (pc->version == GameVersion::PATCH) { - struct sockaddr_storage ss = make_sockaddr_storage( + auto [ss, size] = make_sockaddr_storage( state->proxy_destination_patch.first, - state->proxy_destination_patch.second).first; + state->proxy_destination_patch.second); state->proxy_server->listen(pc->port, pc->version, &ss); } else if (pc->version == GameVersion::BB) { - struct sockaddr_storage ss = make_sockaddr_storage( + auto [ss, size] = make_sockaddr_storage( state->proxy_destination_bb.first, - state->proxy_destination_bb.second).first; + state->proxy_destination_bb.second); state->proxy_server->listen(pc->port, pc->version, &ss); } else { state->proxy_server->listen(pc->port, pc->version); diff --git a/src/Map.cc b/src/Map.cc index e2a1bbc4..22d04745 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -8,8 +8,6 @@ using namespace std; - - string BattleParamsIndex::Entry::str() const { string a1str = format_data_string(this->unknown_a1.data(), this->unknown_a1.bytes()); return string_printf( @@ -31,18 +29,18 @@ void BattleParamsIndex::Table::print(FILE* stream) const { auto print_entry = +[](FILE* stream, const Entry& e) { string a1str = format_data_string(e.unknown_a1.data(), e.unknown_a1.bytes()); fprintf(stream, - "%5hu %5hu %5hu %5hu %5hu %5hu %5hu %5hu %s %5" PRIu32 " %5" PRIu32, - e.atp.load(), - e.psv.load(), - e.evp.load(), - e.hp.load(), - e.dfp.load(), - e.ata.load(), - e.lck.load(), - e.esp.load(), - a1str.c_str(), - e.experience.load(), - e.difficulty.load()); + "%5hu %5hu %5hu %5hu %5hu %5hu %5hu %5hu %s %5" PRIu32 " %5" PRIu32, + e.atp.load(), + e.psv.load(), + e.evp.load(), + e.hp.load(), + e.dfp.load(), + e.ata.load(), + e.lck.load(), + e.esp.load(), + a1str.c_str(), + e.experience.load(), + e.difficulty.load()); }; for (size_t diff = 0; diff < 4; diff++) { @@ -56,8 +54,6 @@ void BattleParamsIndex::Table::print(FILE* stream) const { } } - - BattleParamsIndex::BattleParamsIndex( shared_ptr data_on_ep1, shared_ptr data_on_ep2, @@ -112,9 +108,7 @@ const BattleParamsIndex::Entry& BattleParamsIndex::get( return this->files[!!solo][ep_index].table->difficulty[difficulty][monster_type]; } - - -PSOEnemy::PSOEnemy(uint64_t id) : PSOEnemy(id, 0, 0, 0, 0, "__missing__") { } +PSOEnemy::PSOEnemy(uint64_t id) : PSOEnemy(id, 0, 0, 0, 0, "__missing__") {} PSOEnemy::PSOEnemy( uint64_t id, @@ -123,22 +117,20 @@ PSOEnemy::PSOEnemy( uint32_t rt_index, size_t num_clones, const char* type_name) - : id(id), - source_type(source_type), - hit_flags(0), - last_hit(0), - experience(experience), - rt_index(rt_index), - num_clones(num_clones), - type_name(type_name) { } + : id(id), + source_type(source_type), + hit_flags(0), + last_hit(0), + experience(experience), + rt_index(rt_index), + num_clones(num_clones), + type_name(type_name) {} string PSOEnemy::str() const { return string_printf("[Enemy E-%" PRIX64 " \"%s\" source_type=%hX hit=%02hhX/%hu exp=%" PRIu32 " rt_index=%" PRIX32 " clones=%zu]", this->id, this->type_name, this->source_type, this->hit_flags, this->last_hit, this->experience, this->rt_index, this->num_clones); } - - struct EnemyEntry { uint32_t base; uint16_t reserved0; @@ -174,11 +166,7 @@ vector parse_map( } }; - auto create_enemy = [&]( - const EnemyEntry& e, - ssize_t bp_index, - uint32_t rt_index, - const char* type_name) { + auto create_enemy = [&](const EnemyEntry& e, ssize_t bp_index, uint32_t rt_index, const char* type_name) { const BattleParamsIndex::Entry& bp_entry = battle_params->get( is_solo, episode, difficulty, bp_index); enemies.emplace_back( @@ -423,7 +411,7 @@ vector parse_map( create_enemy(e, 0x1F, 6, "Girtablulu"); break; case 0x0114: // Zu and Pazuzu - create_enemy(e, 0x0B + (e.skin & 0x01) + (alt_enemies ? 0x14: 0x00), + create_enemy(e, 0x0B + (e.skin & 0x01) + (alt_enemies ? 0x14 : 0x00), 7 + (e.skin & 0x01), "(Pazu)?zu"); break; case 0x0115: // Boota family @@ -457,8 +445,6 @@ vector parse_map( return enemies; } - - SetDataTable::SetDataTable(shared_ptr data, bool big_endian) { if (big_endian) { this->load_table_t(data); @@ -523,8 +509,6 @@ void SetDataTable::print(FILE* stream) const { } } - - struct AreaMapFileIndex { const char* name_token; vector variation1_values; @@ -534,127 +518,136 @@ struct AreaMapFileIndex { const char* name_token, vector variation1_values, vector variation2_values) - : name_token(name_token), - variation1_values(variation1_values), - variation2_values(variation2_values) { } + : name_token(name_token), + variation1_values(variation1_values), + variation2_values(variation2_values) {} }; // These are indexed as [episode][is_solo][area], where episode is 0-2 static const vector>> map_file_info = { - { // Episode 1 - { // Non-solo - {"city00", {}, {0}}, - {"forest01", {}, {0, 1, 2, 3, 4}}, - {"forest02", {}, {0, 1, 2, 3, 4}}, - {"cave01", {0, 1, 2}, {0, 1}}, - {"cave02", {0, 1, 2}, {0, 1}}, - {"cave03", {0, 1, 2}, {0, 1}}, - {"machine01", {0, 1, 2}, {0, 1}}, - {"machine02", {0, 1, 2}, {0, 1}}, - {"ancient01", {0, 1, 2}, {0, 1}}, - {"ancient02", {0, 1, 2}, {0, 1}}, - {"ancient03", {0, 1, 2}, {0, 1}}, - {"boss01", {}, {}}, - {"boss02", {}, {}}, - {"boss03", {}, {}}, - {"boss04", {}, {}}, - {nullptr, {}, {}}, + { + // Episode 1 + { + // Non-solo + {"city00", {}, {0}}, + {"forest01", {}, {0, 1, 2, 3, 4}}, + {"forest02", {}, {0, 1, 2, 3, 4}}, + {"cave01", {0, 1, 2}, {0, 1}}, + {"cave02", {0, 1, 2}, {0, 1}}, + {"cave03", {0, 1, 2}, {0, 1}}, + {"machine01", {0, 1, 2}, {0, 1}}, + {"machine02", {0, 1, 2}, {0, 1}}, + {"ancient01", {0, 1, 2}, {0, 1}}, + {"ancient02", {0, 1, 2}, {0, 1}}, + {"ancient03", {0, 1, 2}, {0, 1}}, + {"boss01", {}, {}}, + {"boss02", {}, {}}, + {"boss03", {}, {}}, + {"boss04", {}, {}}, + {nullptr, {}, {}}, + }, + { + // Solo + {"city00", {}, {0}}, + {"forest01", {}, {0, 2, 4}}, + {"forest02", {}, {0, 3, 4}}, + {"cave01", {0, 1, 2}, {0}}, + {"cave02", {0, 1, 2}, {0}}, + {"cave03", {0, 1, 2}, {0}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + }, }, - { // Solo - {"city00", {}, {0}}, - {"forest01", {}, {0, 2, 4}}, - {"forest02", {}, {0, 3, 4}}, - {"cave01", {0, 1, 2}, {0}}, - {"cave02", {0, 1, 2}, {0}}, - {"cave03", {0, 1, 2}, {0}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, + { + // Episode 2 + { + // Non-solo + {"labo00", {}, {0}}, + {"ruins01", {0, 1}, {0}}, + {"ruins02", {0, 1}, {0}}, + {"space01", {0, 1}, {0}}, + {"space02", {0, 1}, {0}}, + {"jungle01", {}, {0, 1, 2}}, + {"jungle02", {}, {0, 1, 2}}, + {"jungle03", {}, {0, 1, 2}}, + {"jungle04", {0, 1}, {0, 1}}, + {"jungle05", {}, {0, 1, 2}}, + {"seabed01", {0, 1}, {0, 1}}, + {"seabed02", {0, 1}, {0, 1}}, + {"boss05", {}, {}}, + {"boss06", {}, {}}, + {"boss07", {}, {}}, + {"boss08", {}, {}}, + }, + { + // Solo + {"labo00", {}, {0}}, + {"ruins01", {0, 1}, {0}}, + {"ruins02", {0, 1}, {0}}, + {"space01", {0, 1}, {0}}, + {"space02", {0, 1}, {0}}, + {"jungle01", {}, {0, 1, 2}}, + {"jungle02", {}, {0, 1, 2}}, + {"jungle03", {}, {0, 1, 2}}, + {"jungle04", {0, 1}, {0, 1}}, + {"jungle05", {}, {0, 1, 2}}, + {"seabed01", {0, 1}, {0}}, + {"seabed02", {0, 1}, {0}}, + {"boss05", {}, {}}, + {"boss06", {}, {}}, + {"boss07", {}, {}}, + {"boss08", {}, {}}, + }, }, - }, - { // Episode 2 - { // Non-solo - {"labo00", {}, {0}}, - {"ruins01", {0, 1}, {0}}, - {"ruins02", {0, 1}, {0}}, - {"space01", {0, 1}, {0}}, - {"space02", {0, 1}, {0}}, - {"jungle01", {}, {0, 1, 2}}, - {"jungle02", {}, {0, 1, 2}}, - {"jungle03", {}, {0, 1, 2}}, - {"jungle04", {0, 1}, {0, 1}}, - {"jungle05", {}, {0, 1, 2}}, - {"seabed01", {0, 1}, {0, 1}}, - {"seabed02", {0, 1}, {0, 1}}, - {"boss05", {}, {}}, - {"boss06", {}, {}}, - {"boss07", {}, {}}, - {"boss08", {}, {}}, + { + // Episode 4 + { + // Non-solo + {"city02", {0}, {0}}, + {"wilds01", {0}, {0, 1, 2}}, + {"wilds01", {1}, {0, 1, 2}}, + {"wilds01", {2}, {0, 1, 2}}, + {"wilds01", {3}, {0, 1, 2}}, + {"crater01", {0}, {0, 1, 2}}, + {"desert01", {0, 1, 2}, {0}}, + {"desert02", {0}, {0, 1, 2}}, + {"desert03", {0, 1, 2}, {0}}, + {"boss09", {0}, {0}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + }, + { + // Solo + {"city02", {0}, {0}}, + {"wilds01", {0}, {0, 1, 2}}, + {"wilds01", {1}, {0, 1, 2}}, + {"wilds01", {2}, {0, 1, 2}}, + {"wilds01", {3}, {0, 1, 2}}, + {"crater01", {0}, {0, 1, 2}}, + {"desert01", {0, 1, 2}, {0}}, + {"desert02", {0}, {0, 1, 2}}, + {"desert03", {0, 1, 2}, {0}}, + {"boss09", {0}, {0}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + {nullptr, {}, {}}, + }, }, - { // Solo - {"labo00", {}, {0}}, - {"ruins01", {0, 1}, {0}}, - {"ruins02", {0, 1}, {0}}, - {"space01", {0, 1}, {0}}, - {"space02", {0, 1}, {0}}, - {"jungle01", {}, {0, 1, 2}}, - {"jungle02", {}, {0, 1, 2}}, - {"jungle03", {}, {0, 1, 2}}, - {"jungle04", {0, 1}, {0, 1}}, - {"jungle05", {}, {0, 1, 2}}, - {"seabed01", {0, 1}, {0}}, - {"seabed02", {0, 1}, {0}}, - {"boss05", {}, {}}, - {"boss06", {}, {}}, - {"boss07", {}, {}}, - {"boss08", {}, {}}, - }, - }, - { // Episode 4 - { // Non-solo - {"city02", {0}, {0}}, - {"wilds01", {0}, {0, 1, 2}}, - {"wilds01", {1}, {0, 1, 2}}, - {"wilds01", {2}, {0, 1, 2}}, - {"wilds01", {3}, {0, 1, 2}}, - {"crater01", {0}, {0, 1, 2}}, - {"desert01", {0, 1, 2}, {0}}, - {"desert02", {0}, {0, 1, 2}}, - {"desert03", {0, 1, 2}, {0}}, - {"boss09", {0}, {0}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - }, - { // Solo - {"city02", {0}, {0}}, - {"wilds01", {0}, {0, 1, 2}}, - {"wilds01", {1}, {0, 1, 2}}, - {"wilds01", {2}, {0, 1, 2}}, - {"wilds01", {3}, {0, 1, 2}}, - {"crater01", {0}, {0, 1, 2}}, - {"desert01", {0, 1, 2}, {0}}, - {"desert02", {0}, {0, 1, 2}}, - {"desert03", {0, 1, 2}, {0}}, - {"boss09", {0}, {0}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - {nullptr, {}, {}}, - }, - }, }; const vector>& map_file_info_for_episode(Episode ep) { @@ -688,10 +681,8 @@ void generate_variations( variations[z * 2 + 0] = 0; variations[z * 2 + 1] = 0; } else { - variations[z * 2 + 0] = (a->variation1_values.size() < 2) ? 0 : - ((*random)() % a->variation1_values.size()); - variations[z * 2 + 1] = (a->variation2_values.size() < 2) ? 0 : - ((*random)() % a->variation2_values.size()); + variations[z * 2 + 0] = (a->variation1_values.size() < 2) ? 0 : ((*random)() % a->variation1_values.size()); + variations[z * 2 + 1] = (a->variation2_values.size() < 2) ? 0 : ((*random)() % a->variation2_values.size()); } } } diff --git a/src/Map.hh b/src/Map.hh index 7cbf4183..279fc8ef 100644 --- a/src/Map.hh +++ b/src/Map.hh @@ -11,15 +11,13 @@ #include "StaticGameData.hh" #include "Text.hh" - - class BattleParamsIndex { public: struct Entry { le_uint16_t atp; // attack power le_uint16_t psv; // perseverance (intelligence?) le_uint16_t evp; // evasion - le_uint16_t hp; // hit points + le_uint16_t hp; // hit points le_uint16_t dfp; // defense le_uint16_t ata; // accuracy le_uint16_t lck; // luck @@ -58,8 +56,6 @@ private: LoadedFile files[2][3]; }; - - struct PSOEnemy { uint64_t id; uint16_t source_type; @@ -90,8 +86,6 @@ std::vector parse_map( std::shared_ptr data, bool alt_enemies); - - // TODO: This class is currently unused. It would be nice if we could use this // to generate variations and link to the corresponding map filenames, but it // seems that SetDataTable.rel files link to map filenames that don't actually @@ -121,8 +115,6 @@ private: std::vector>> entries; }; - - void generate_variations( parray& variations, std::shared_ptr random, diff --git a/src/Menu.cc b/src/Menu.cc index 079a8776..f548a740 100644 --- a/src/Menu.cc +++ b/src/Menu.cc @@ -2,8 +2,10 @@ using namespace std; - - -MenuItem::MenuItem(uint32_t item_id, const u16string& name, - const u16string& description, uint32_t flags) : item_id(item_id), name(name), - description(description), flags(flags) { } +MenuItem::MenuItem( + uint32_t item_id, const u16string& name, + const u16string& description, uint32_t flags) + : item_id(item_id), + name(name), + description(description), + flags(flags) {} diff --git a/src/Menu.hh b/src/Menu.hh index 7e14d261..b33bb757 100644 --- a/src/Menu.hh +++ b/src/Menu.hh @@ -4,8 +4,6 @@ #include - - // Note: These aren't enums because neither enum nor enum class does what we // want. Specifically, we need GO_BACK to be valid in multiple enums (and enums // aren't namespaced unless they're enum classes), so we can't use enums. But we @@ -13,68 +11,66 @@ // casting values all over the place, so we can't use enum classes either. namespace MenuID { - constexpr uint32_t MAIN = 0x11000011; - constexpr uint32_t INFORMATION = 0x22000022; - constexpr uint32_t LOBBY = 0x33000033; - constexpr uint32_t GAME = 0x44000044; - constexpr uint32_t QUEST = 0x55000055; - constexpr uint32_t QUEST_FILTER = 0x66000066; - constexpr uint32_t PROXY_DESTINATIONS = 0x77000077; - constexpr uint32_t PROGRAMS = 0x88000088; - constexpr uint32_t PATCHES = 0x99000099; - constexpr uint32_t PROXY_OPTIONS = 0xAA0000AA; - constexpr uint32_t TOURNAMENTS = 0xBB0000BB; - constexpr uint32_t TOURNAMENTS_FOR_SPEC = 0xBB1111BB; - constexpr uint32_t TOURNAMENT_ENTRIES = 0xCC0000CC; -} +constexpr uint32_t MAIN = 0x11000011; +constexpr uint32_t INFORMATION = 0x22000022; +constexpr uint32_t LOBBY = 0x33000033; +constexpr uint32_t GAME = 0x44000044; +constexpr uint32_t QUEST = 0x55000055; +constexpr uint32_t QUEST_FILTER = 0x66000066; +constexpr uint32_t PROXY_DESTINATIONS = 0x77000077; +constexpr uint32_t PROGRAMS = 0x88000088; +constexpr uint32_t PATCHES = 0x99000099; +constexpr uint32_t PROXY_OPTIONS = 0xAA0000AA; +constexpr uint32_t TOURNAMENTS = 0xBB0000BB; +constexpr uint32_t TOURNAMENTS_FOR_SPEC = 0xBB1111BB; +constexpr uint32_t TOURNAMENT_ENTRIES = 0xCC0000CC; +} // namespace MenuID namespace MainMenuItemID { - constexpr uint32_t GO_TO_LOBBY = 0x11222211; - constexpr uint32_t INFORMATION = 0x11333311; - constexpr uint32_t DOWNLOAD_QUESTS = 0x11444411; - constexpr uint32_t PROXY_DESTINATIONS = 0x11555511; - constexpr uint32_t PATCHES = 0x11666611; - constexpr uint32_t PROGRAMS = 0x11777711; - constexpr uint32_t DISCONNECT = 0x11888811; - constexpr uint32_t CLEAR_LICENSE = 0x11999911; -} +constexpr uint32_t GO_TO_LOBBY = 0x11222211; +constexpr uint32_t INFORMATION = 0x11333311; +constexpr uint32_t DOWNLOAD_QUESTS = 0x11444411; +constexpr uint32_t PROXY_DESTINATIONS = 0x11555511; +constexpr uint32_t PATCHES = 0x11666611; +constexpr uint32_t PROGRAMS = 0x11777711; +constexpr uint32_t DISCONNECT = 0x11888811; +constexpr uint32_t CLEAR_LICENSE = 0x11999911; +} // namespace MainMenuItemID namespace InformationMenuItemID { - constexpr uint32_t GO_BACK = 0x22FFFF22; +constexpr uint32_t GO_BACK = 0x22FFFF22; } namespace ProxyDestinationsMenuItemID { - constexpr uint32_t GO_BACK = 0x77FFFF77; - constexpr uint32_t OPTIONS = 0x77EEEE77; -} +constexpr uint32_t GO_BACK = 0x77FFFF77; +constexpr uint32_t OPTIONS = 0x77EEEE77; +} // namespace ProxyDestinationsMenuItemID namespace ProgramsMenuItemID { - constexpr uint32_t GO_BACK = 0x88FFFF88; +constexpr uint32_t GO_BACK = 0x88FFFF88; } namespace PatchesMenuItemID { - constexpr uint32_t GO_BACK = 0x99FFFF99; +constexpr uint32_t GO_BACK = 0x99FFFF99; } namespace ProxyOptionsMenuItemID { - constexpr uint32_t GO_BACK = 0xAAFFFFAA; - constexpr uint32_t CHAT_COMMANDS = 0xAA0000AA; - constexpr uint32_t CHAT_FILTER = 0xAA1111AA; - constexpr uint32_t PLAYER_NOTIFICATIONS = 0xAA2222AA; - constexpr uint32_t INFINITE_HP = 0xAA3333AA; - constexpr uint32_t INFINITE_TP = 0xAA4444AA; - constexpr uint32_t SWITCH_ASSIST = 0xAA5555AA; - constexpr uint32_t BLOCK_EVENTS = 0xAA6666AA; - constexpr uint32_t BLOCK_PATCHES = 0xAA7777AA; - constexpr uint32_t SAVE_FILES = 0xAA8888AA; - constexpr uint32_t RED_NAME = 0xAA9999AA; - constexpr uint32_t BLANK_NAME = 0xAAAAAAAA; - constexpr uint32_t SUPPRESS_LOGIN = 0xAABBBBAA; - constexpr uint32_t SKIP_CARD = 0xAACCCCAA; - constexpr uint32_t EP3_INFINITE_MESETA = 0xAADDDDAA; -} - - +constexpr uint32_t GO_BACK = 0xAAFFFFAA; +constexpr uint32_t CHAT_COMMANDS = 0xAA0000AA; +constexpr uint32_t CHAT_FILTER = 0xAA1111AA; +constexpr uint32_t PLAYER_NOTIFICATIONS = 0xAA2222AA; +constexpr uint32_t INFINITE_HP = 0xAA3333AA; +constexpr uint32_t INFINITE_TP = 0xAA4444AA; +constexpr uint32_t SWITCH_ASSIST = 0xAA5555AA; +constexpr uint32_t BLOCK_EVENTS = 0xAA6666AA; +constexpr uint32_t BLOCK_PATCHES = 0xAA7777AA; +constexpr uint32_t SAVE_FILES = 0xAA8888AA; +constexpr uint32_t RED_NAME = 0xAA9999AA; +constexpr uint32_t BLANK_NAME = 0xAAAAAAAA; +constexpr uint32_t SUPPRESS_LOGIN = 0xAABBBBAA; +constexpr uint32_t SKIP_CARD = 0xAACCCCAA; +constexpr uint32_t EP3_INFINITE_MESETA = 0xAADDDDAA; +} // namespace ProxyOptionsMenuItemID struct MenuItem { enum Flag { diff --git a/src/NetworkAddresses.cc b/src/NetworkAddresses.cc index 73add1a2..50f1396d 100644 --- a/src/NetworkAddresses.cc +++ b/src/NetworkAddresses.cc @@ -1,14 +1,12 @@ #include "NetworkAddresses.hh" -#include -#include -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include #include #include @@ -17,19 +15,17 @@ using namespace std; - - uint32_t resolve_address(const char* address) { - struct addrinfo *res0; + struct addrinfo* res0; if (getaddrinfo(address, nullptr, nullptr, &res0)) { auto e = string_for_error(errno); - throw runtime_error(string_printf("can\'t resolve hostname %s: %s", address, - e.c_str())); + throw runtime_error(string_printf( + "can\'t resolve hostname %s: %s", address, e.c_str())); } - std::unique_ptr res0_unique( + std::unique_ptr res0_unique( res0, freeaddrinfo); - struct addrinfo *res4 = nullptr; + struct addrinfo* res4 = nullptr; for (struct addrinfo* res = res0; res; res = res->ai_next) { if (res->ai_family == AF_INET) { res4 = res; @@ -51,7 +47,7 @@ map get_local_addresses() { throw runtime_error(string_printf("failed to get interface addresses: %s", s.c_str())); } - unique_ptr ifa(ifa_raw, freeifaddrs); + unique_ptr ifa(ifa_raw, freeifaddrs); map ret; for (struct ifaddrs* i = ifa.get(); i; i = i->ifa_next) { diff --git a/src/NetworkAddresses.hh b/src/NetworkAddresses.hh index 5420c640..7f894397 100644 --- a/src/NetworkAddresses.hh +++ b/src/NetworkAddresses.hh @@ -6,8 +6,6 @@ #include #include - - // PSO is IPv4-only, so we just treat addresses as uint32_t everywhere because // it's easier diff --git a/src/PSOEncryption.cc b/src/PSOEncryption.cc index 40ae54bc..1b85a65f 100644 --- a/src/PSOEncryption.cc +++ b/src/PSOEncryption.cc @@ -3,29 +3,23 @@ #include #include -#include -#include #include #include +#include +#include using namespace std; - - // TODO: fix style in this file, especially in psobb functions - - // Most ciphers used by PSO are symmetric; alias decrypt to encrypt by default void PSOEncryption::decrypt(void* data, size_t size, bool advance) { this->encrypt(data, size, advance); } - - PSOLFGEncryption::PSOLFGEncryption( uint32_t seed, size_t stream_length, size_t end_offset) - : stream(stream_length, 0), offset(0), end_offset(end_offset), seed(seed) { } + : stream(stream_length, 0), offset(0), end_offset(end_offset), seed(seed) {} uint32_t PSOLFGEncryption::next(bool advance) { if (this->offset == this->end_offset) { @@ -109,10 +103,8 @@ void PSOLFGEncryption::encrypt_both_endian( } } - - PSOV2Encryption::PSOV2Encryption(uint32_t seed) - : PSOLFGEncryption(seed, this->STREAM_LENGTH + 1, this->STREAM_LENGTH) { + : PSOLFGEncryption(seed, this->STREAM_LENGTH + 1, this->STREAM_LENGTH) { uint32_t esi, ebx, edi, eax, edx, var1; esi = 1; ebx = this->seed; @@ -163,10 +155,8 @@ PSOEncryption::Type PSOV2Encryption::type() const { return Type::V2; } - - PSOV3Encryption::PSOV3Encryption(uint32_t seed) - : PSOLFGEncryption(seed, this->STREAM_LENGTH, this->STREAM_LENGTH) { + : PSOLFGEncryption(seed, this->STREAM_LENGTH, this->STREAM_LENGTH) { uint32_t x, y, basekey, source1, source2, source3; basekey = 0; @@ -219,11 +209,9 @@ PSOEncryption::Type PSOV3Encryption::type() const { return Type::V3; } - - PSOBBEncryption::PSOBBEncryption( const KeyFile& key, const void* original_seed, size_t seed_size) - : state(key) { + : state(key) { this->apply_seed(original_seed, seed_size); } @@ -238,14 +226,14 @@ void PSOBBEncryption::encrypt(void* vdata, size_t size, bool advance) { for (size_t y = 0; y < 4; y += 2) { dwords[x] ^= this->state.initial_keys.as32[y]; dwords[x + 1] ^= ((this->state.private_keys.as32[dwords[x] >> 24] + - this->state.private_keys.as32[((dwords[x] >> 16) & 0xFF) + 0x100]) ^ - this->state.private_keys.as32[((dwords[x] >> 8) & 0xFF) + 0x200]) + - this->state.private_keys.as32[(dwords[x] & 0xFF) + 0x300]; + this->state.private_keys.as32[((dwords[x] >> 16) & 0xFF) + 0x100]) ^ + this->state.private_keys.as32[((dwords[x] >> 8) & 0xFF) + 0x200]) + + this->state.private_keys.as32[(dwords[x] & 0xFF) + 0x300]; dwords[x + 1] ^= this->state.initial_keys.as32[y + 1]; dwords[x] ^= ((this->state.private_keys.as32[dwords[x + 1] >> 24] + - this->state.private_keys.as32[(dwords[x + 1] >> 16 & 0xFF) + 0x100]) ^ - this->state.private_keys.as32[(dwords[x + 1] >> 8 & 0xFF) + 0x200]) + - this->state.private_keys.as32[(dwords[x + 1] & 0xFF) + 0x300]; + this->state.private_keys.as32[(dwords[x + 1] >> 16 & 0xFF) + 0x100]) ^ + this->state.private_keys.as32[(dwords[x + 1] >> 8 & 0xFF) + 0x200]) + + this->state.private_keys.as32[(dwords[x + 1] & 0xFF) + 0x300]; } dwords[x] ^= this->state.initial_keys.as32[4]; dwords[x + 1] ^= this->state.initial_keys.as32[5]; @@ -335,14 +323,14 @@ void PSOBBEncryption::decrypt(void* vdata, size_t size, bool advance) { for (size_t y = 4; y > 0; y -= 2) { dwords[x] = dwords[x] ^ this->state.initial_keys.as32[y + 1]; dwords[x + 1] ^= ((this->state.private_keys.as32[dwords[x] >> 24] + - this->state.private_keys.as32[((dwords[x] >> 16) & 0xFF) + 0x100]) ^ - this->state.private_keys.as32[((dwords[x] >> 8) & 0xFF) + 0x200]) + - this->state.private_keys.as32[(dwords[x] & 0xFF) + 0x300]; + this->state.private_keys.as32[((dwords[x] >> 16) & 0xFF) + 0x100]) ^ + this->state.private_keys.as32[((dwords[x] >> 8) & 0xFF) + 0x200]) + + this->state.private_keys.as32[(dwords[x] & 0xFF) + 0x300]; dwords[x + 1] ^= this->state.initial_keys.as32[y]; dwords[x] ^= ((this->state.private_keys.as32[dwords[x + 1] >> 24] + - this->state.private_keys.as32[((dwords[x + 1] >> 16) & 0xFF) + 0x100]) ^ - this->state.private_keys.as32[((dwords[x + 1] >> 8) & 0xFF) + 0x200]) + - this->state.private_keys.as32[(dwords[x + 1] & 0xFF) + 0x300]; + this->state.private_keys.as32[((dwords[x + 1] >> 16) & 0xFF) + 0x100]) ^ + this->state.private_keys.as32[((dwords[x + 1] >> 8) & 0xFF) + 0x200]) + + this->state.private_keys.as32[(dwords[x + 1] & 0xFF) + 0x300]; } dwords[x] ^= this->state.initial_keys.as32[1]; dwords[x + 1] ^= this->state.initial_keys.as32[0]; @@ -432,7 +420,8 @@ void PSOBBEncryption::tfs1_scramble(uint32_t* out1, uint32_t* out2) const { b ^= (((this->state.private_keys.as32[a >> 24] + this->state.private_keys.as32[((a >> 16) & 0xFF) + 0x100]) ^ this->state.private_keys.as32[((a >> 8) & 0xFF) + 0x200]) + - this->state.private_keys.as32[(a & 0xFF) + 0x300]) ^ this->state.initial_keys.as32[x + 1]; + this->state.private_keys.as32[(a & 0xFF) + 0x300]) ^ + this->state.initial_keys.as32[x + 1]; a ^= ((this->state.private_keys.as32[b >> 24] + this->state.private_keys.as32[((b >> 16) & 0xFF) + 0x100]) ^ this->state.private_keys.as32[((b >> 8) & 0xFF) + 0x200]) + @@ -608,7 +597,7 @@ void PSOBBEncryption::apply_seed(const void* original_seed, size_t seed_size) { esi = this->state.initial_keys.as32[17]; esi = esi ^ eax; this->state.initial_keys.as32[(edi / 4)] = esi; - this->state.initial_keys.as32[(edi / 4)+1] = ecx; + this->state.initial_keys.as32[(edi / 4) + 1] = ecx; edi = edi + 8; } @@ -695,13 +684,11 @@ void PSOBBEncryption::apply_seed(const void* original_seed, size_t seed_size) { } } - - PSOV2OrV3DetectorEncryption::PSOV2OrV3DetectorEncryption( uint32_t key, const std::unordered_set& v2_matches, const std::unordered_set& v3_matches) - : key(key), v2_matches(v2_matches), v3_matches(v3_matches) { } + : key(key), v2_matches(v2_matches), v3_matches(v3_matches) {} void PSOV2OrV3DetectorEncryption::encrypt(void* data, size_t size, bool advance) { if (!this->active_crypt) { @@ -745,11 +732,9 @@ PSOEncryption::Type PSOV2OrV3DetectorEncryption::type() const { return this->active_crypt->type(); } - - PSOV2OrV3ImitatorEncryption::PSOV2OrV3ImitatorEncryption( uint32_t key, std::shared_ptr detector_crypt) - : key(key), detector_crypt(detector_crypt) { } + : key(key), detector_crypt(detector_crypt) {} void PSOV2OrV3ImitatorEncryption::encrypt(void* data, size_t size, bool advance) { if (!this->active_crypt) { @@ -772,16 +757,14 @@ PSOEncryption::Type PSOV2OrV3ImitatorEncryption::type() const { return this->active_crypt->type(); } - - PSOBBMultiKeyDetectorEncryption::PSOBBMultiKeyDetectorEncryption( const vector>& possible_keys, const unordered_set& expected_first_data, const void* seed, size_t seed_size) - : possible_keys(possible_keys), - expected_first_data(expected_first_data), - seed(reinterpret_cast(seed), seed_size) { } + : possible_keys(possible_keys), + expected_first_data(expected_first_data), + seed(reinterpret_cast(seed), seed_size) {} void PSOBBMultiKeyDetectorEncryption::encrypt(void* data, size_t size, bool advance) { if (!this->active_crypt.get()) { @@ -819,16 +802,14 @@ PSOEncryption::Type PSOBBMultiKeyDetectorEncryption::type() const { return Type::BB; } - - PSOBBMultiKeyImitatorEncryption::PSOBBMultiKeyImitatorEncryption( shared_ptr detector_crypt, const void* seed, size_t seed_size, bool jsd1_use_detector_seed) - : detector_crypt(detector_crypt), - seed(reinterpret_cast(seed), seed_size), - jsd1_use_detector_seed(jsd1_use_detector_seed) { } + : detector_crypt(detector_crypt), + seed(reinterpret_cast(seed), seed_size), + jsd1_use_detector_seed(jsd1_use_detector_seed) {} void PSOBBMultiKeyImitatorEncryption::encrypt(void* data, size_t size, bool advance) { this->ensure_crypt()->encrypt(data, size, advance); @@ -863,8 +844,6 @@ shared_ptr PSOBBMultiKeyImitatorEncryption::ensure_crypt() { return this->active_crypt; } - - JSD0Encryption::JSD0Encryption(const void* seed, size_t seed_size) : key(0) { const uint8_t* bytes = reinterpret_cast(seed); for (size_t z = 0; z < seed_size; z++) { @@ -892,8 +871,6 @@ PSOEncryption::Type JSD0Encryption::type() const { return Type::JSD0; } - - void decrypt_trivial_gci_data(void* data, size_t size, uint8_t basis) { uint8_t* bytes = reinterpret_cast(data); uint8_t key = basis + 0x80; diff --git a/src/PSOEncryption.hh b/src/PSOEncryption.hh index 3c85376c..4cc7d1ba 100644 --- a/src/PSOEncryption.hh +++ b/src/PSOEncryption.hh @@ -4,14 +4,12 @@ #include #include +#include #include #include -#include #include "Text.hh" // for parray - - class PSOEncryption { public: enum class Type { @@ -39,8 +37,6 @@ protected: PSOEncryption() = default; }; - - class PSOLFGEncryption : public PSOEncryption { public: virtual void encrypt(void* data, size_t size, bool advance = true); @@ -91,8 +87,6 @@ protected: static constexpr size_t STREAM_LENGTH = 521; }; - - class PSOBBEncryption : public PSOEncryption { public: enum Subtype : uint8_t { @@ -109,14 +103,14 @@ public: uint8_t jsd1_stream_offset; parray as8; parray as32; - InitialKeys() : as32() { } - InitialKeys(const InitialKeys& other) : as32(other.as32) { } + InitialKeys() : as32() {} + InitialKeys(const InitialKeys& other) : as32(other.as32) {} } __attribute__((packed)); union PrivateKeys { parray as8; parray as32; - PrivateKeys() : as32() { } - PrivateKeys(const PrivateKeys& other) : as32(other.as32) { } + PrivateKeys() : as32() {} + PrivateKeys(const PrivateKeys& other) : as32(other.as32) {} } __attribute__((packed)); InitialKeys initial_keys; PrivateKeys private_keys; @@ -137,9 +131,6 @@ protected: void apply_seed(const void* original_seed, size_t seed_size); }; - - - // The following classes provide support for automatically detecting which type // of encryption a client is using based on their initial response to the server @@ -176,8 +167,6 @@ protected: std::shared_ptr active_crypt; }; - - // The following classes provide support for multiple PSOBB private keys, and // the ability to automatically detect which key the client is using based on // the first 8 bytes they send @@ -232,8 +221,6 @@ protected: bool jsd1_use_detector_seed; }; - - class JSD0Encryption : public PSOEncryption { public: JSD0Encryption(const void* seed, size_t seed_size); @@ -247,6 +234,4 @@ private: uint8_t key; }; - - void decrypt_trivial_gci_data(void* data, size_t size, uint8_t basis); diff --git a/src/PSOGCObjectGraph.cc b/src/PSOGCObjectGraph.cc index 75afcd96..c9887782 100644 --- a/src/PSOGCObjectGraph.cc +++ b/src/PSOGCObjectGraph.cc @@ -4,8 +4,6 @@ using namespace std; - - struct TObjectVTable { be_uint32_t unused_a1; be_uint32_t unused_a2; @@ -36,7 +34,8 @@ shared_ptr PSOGCObjectGraph::parse_vtable_memo( StringReader& r, uint32_t addr) { try { return this->all_vtables.at(addr); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } const auto& vt = r.pget(addr & 0x01FFFFFF); auto ret = this->all_vtables.emplace(addr, new VTable()).first->second; @@ -52,7 +51,8 @@ shared_ptr PSOGCObjectGraph::parse_object_memo( StringReader& r, uint32_t addr) { try { return this->all_objects.at(addr); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } const auto& obj = r.pget(addr & 0x01FFFFFF); string type_name = r.pget_cstr(obj.type_name_addr & 0x01FFFFFF); @@ -79,22 +79,20 @@ void PSOGCObjectGraph::print(FILE* stream) const { this->root->print(stream); } - - void PSOGCObjectGraph::Object::print(FILE* stream, size_t indent_level) const { for (size_t z = 0; z < indent_level; z++) { fputc(' ', stream); fputc(' ', stream); } fprintf(stream, "%s +%04hX @ %08" PRIX32 " (VT %08" PRIX32 ": destroy=%08" PRIX32 " update=%08" PRIX32 " render=%08" PRIX32 " render_shadow=%08" PRIX32 ")\n", - this->type_name.c_str(), - this->flags, - this->address, - this->vtable->address, - this->vtable->destroy_addr, - this->vtable->update_addr, - this->vtable->render_addr, - this->vtable->render_shadow_addr); + this->type_name.c_str(), + this->flags, + this->address, + this->vtable->address, + this->vtable->destroy_addr, + this->vtable->update_addr, + this->vtable->render_addr, + this->vtable->render_shadow_addr); for (const auto& child : this->children) { child->print(stream, indent_level + 1); } diff --git a/src/PSOGCObjectGraph.hh b/src/PSOGCObjectGraph.hh index 12b16194..162d71f4 100644 --- a/src/PSOGCObjectGraph.hh +++ b/src/PSOGCObjectGraph.hh @@ -9,8 +9,6 @@ #include #include - - struct PSOGCObjectGraph { PSOGCObjectGraph(const std::string& memory_data, uint32_t root_address); diff --git a/src/PSOProtocol.cc b/src/PSOProtocol.cc index d1660f0b..b67303d3 100644 --- a/src/PSOProtocol.cc +++ b/src/PSOProtocol.cc @@ -2,19 +2,15 @@ #include -#include #include +#include #include "Text.hh" using namespace std; - - extern bool use_terminal_colors; - - PSOCommandHeader::PSOCommandHeader() { this->bb.size = 0; this->bb.command = 0; @@ -144,8 +140,6 @@ void PSOCommandHeader::set_flag(GameVersion version, uint32_t flag) { } } - - void check_size_v(size_t size, size_t min_size, size_t max_size) { if (size < min_size) { throw std::runtime_error(string_printf( @@ -162,8 +156,6 @@ void check_size_v(size_t size, size_t min_size, size_t max_size) { } } - - std::string prepend_command_header( GameVersion version, bool encryption_enabled, diff --git a/src/PSOProtocol.hh b/src/PSOProtocol.hh index 09535fdc..d2d99290 100644 --- a/src/PSOProtocol.hh +++ b/src/PSOProtocol.hh @@ -1,13 +1,13 @@ #pragma once -#include #include +#include #include #include -#include "Version.hh" #include "PSOEncryption.hh" +#include "Version.hh" struct PSOCommandHeaderPC { le_uint16_t size; diff --git a/src/PatchFileIndex.cc b/src/PatchFileIndex.cc index 0e7e4770..9adafdc9 100644 --- a/src/PatchFileIndex.cc +++ b/src/PatchFileIndex.cc @@ -4,19 +4,19 @@ #include #include -#include #include #include #include +#include #include "Loggers.hh" using namespace std; - - PatchFileIndex::File::File(PatchFileIndex* index) - : index(index), crc32(0), size(0) { } + : index(index), + crc32(0), + size(0) {} std::shared_ptr PatchFileIndex::File::load_data() { if (!this->loaded_data) { @@ -29,10 +29,8 @@ std::shared_ptr PatchFileIndex::File::load_data() { return this->loaded_data; } - - PatchFileIndex::PatchFileIndex(const string& root_dir) - : root_dir(root_dir) { + : root_dir(root_dir) { string metadata_cache_filename = root_dir + "/.metadata-cache.json"; shared_ptr metadata_cache_json; @@ -113,10 +111,10 @@ PatchFileIndex::PatchFileIndex(const string& root_dir) chunk_crcs_item.emplace_back(make_json_int(chunk_crc)); } vector> new_cache_item({ - make_json_int(f->size), - make_json_int(st.st_mtime), - make_json_int(f->crc32), - make_json_list(move(chunk_crcs_item)), + make_json_int(f->size), + make_json_int(st.st_mtime), + make_json_int(f->crc32), + make_json_list(move(chunk_crcs_item)), }); new_metadata_cache_json->as_dict().emplace( relative_item_path, make_json_list(move(new_cache_item))); @@ -132,10 +130,12 @@ PatchFileIndex::PatchFileIndex(const string& root_dir) this->files_by_patch_order.emplace_back(f); this->files_by_name.emplace(relative_item_path, f); if (compute_crc32s_message.empty()) { - patch_index_log.info("Added file %s (%" PRIu32 " bytes; %zu chunks; %08" PRIX32 " from cache)", + patch_index_log.info( + "Added file %s (%" PRIu32 " bytes; %zu chunks; %08" PRIX32 " from cache)", full_item_path.c_str(), f->size, f->chunk_crcs.size(), f->crc32); } else { - patch_index_log.info("Added file %s (%" PRIu32 " bytes; %zu chunks; %08" PRIX32 " [%s])", + patch_index_log.info( + "Added file %s (%" PRIu32 " bytes; %zu chunks; %08" PRIX32 " [%s])", full_item_path.c_str(), f->size, f->chunk_crcs.size(), f->crc32, compute_crc32s_message.c_str()); } } diff --git a/src/PatchFileIndex.hh b/src/PatchFileIndex.hh index 0f6ac7e7..df546529 100644 --- a/src/PatchFileIndex.hh +++ b/src/PatchFileIndex.hh @@ -2,13 +2,11 @@ #include +#include +#include #include #include -#include #include -#include - - struct PatchFileIndex { explicit PatchFileIndex(const std::string& root_dir); @@ -42,10 +40,13 @@ struct PatchFileChecksumRequest { bool response_received; explicit PatchFileChecksumRequest(std::shared_ptr file) - : file(file), crc32(0), size(0), response_received(false) { } + : file(file), + crc32(0), + size(0), + response_received(false) {} inline bool needs_update() const { return !this->response_received || - (this->crc32 != this->file->crc32) || - (this->size != this->file->size); + (this->crc32 != this->file->crc32) || + (this->size != this->file->size); } }; diff --git a/src/Player.cc b/src/Player.cc index c98573b4..a6050d6a 100644 --- a/src/Player.cc +++ b/src/Player.cc @@ -4,12 +4,12 @@ #include #include -#include #include #include +#include -#include "ItemData.hh" #include "FileContentsCache.hh" +#include "ItemData.hh" #include "Loggers.hh" #include "StaticGameData.hh" #include "Text.hh" @@ -17,8 +17,6 @@ using namespace std; - - // Originally there was going to be a language-based header, but then I decided // against it. These strings were already in use for that parser, so I didn't // bother changing them. @@ -27,38 +25,40 @@ static const string PLAYER_FILE_SIGNATURE = static const string ACCOUNT_FILE_SIGNATURE = "newserv account file format; 7 sections present; sequential;"; - - static FileContentsCache player_files_cache(300 * 1000 * 1000); - - PlayerStats::PlayerStats() noexcept - : atp(0), mst(0), evp(0), hp(0), dfp(0), ata(0), lck(0) { } + : atp(0), + mst(0), + evp(0), + hp(0), + dfp(0), + ata(0), + lck(0) {} PlayerDispDataDCPCV3::PlayerDispDataDCPCV3() noexcept - : level(0), - experience(0), - meseta(0), - unknown_a2(0), - name_color(0), - extra_model(0), - name_color_checksum(0), - section_id(0), - char_class(0), - v2_flags(0), - version(0), - v1_flags(0), - costume(0), - skin(0), - face(0), - head(0), - hair(0), - hair_r(0), - hair_g(0), - hair_b(0), - proportion_x(0), - proportion_y(0) { } + : level(0), + experience(0), + meseta(0), + unknown_a2(0), + name_color(0), + extra_model(0), + name_color_checksum(0), + section_id(0), + char_class(0), + v2_flags(0), + version(0), + v1_flags(0), + costume(0), + skin(0), + face(0), + head(0), + hair(0), + hair_r(0), + hair_g(0), + hair_b(0), + proportion_x(0), + proportion_y(0) {} void PlayerDispDataDCPCV3::enforce_v2_limits() { // V1/V2 have fewer classes, so we'll substitute some here @@ -119,31 +119,29 @@ PlayerDispDataBB PlayerDispDataDCPCV3::to_bb() const { return bb; } - - PlayerDispDataBB::PlayerDispDataBB() noexcept - : level(0), - experience(0), - meseta(0), - unknown_a2(0), - name_color(0), - extra_model(0), - name_color_checksum(0), - section_id(0), - char_class(0), - v2_flags(0), - version(0), - v1_flags(0), - costume(0), - skin(0), - face(0), - head(0), - hair(0), - hair_r(0), - hair_g(0), - hair_b(0), - proportion_x(0), - proportion_y(0) { } + : level(0), + experience(0), + meseta(0), + unknown_a2(0), + name_color(0), + extra_model(0), + name_color_checksum(0), + section_id(0), + char_class(0), + v2_flags(0), + version(0), + v1_flags(0), + costume(0), + skin(0), + face(0), + head(0), + hair(0), + hair_r(0), + hair_g(0), + hair_b(0), + proportion_x(0), + proportion_y(0) {} PlayerDispDataDCPCV3 PlayerDispDataBB::to_dcpcv3() const { PlayerDispDataDCPCV3 ret; @@ -263,48 +261,44 @@ void PlayerDispDataBB::apply_dressing_room(const PlayerDispDataBBPreview& pre) { this->name = pre.name; } - - PlayerDispDataBBPreview::PlayerDispDataBBPreview() noexcept - : experience(0), - level(0), - unknown_a2(0), - name_color(0), - extra_model(0), - name_color_checksum(0), - section_id(0), - char_class(0), - v2_flags(0), - version(0), - v1_flags(0), - costume(0), - skin(0), - face(0), - head(0), - hair(0), - hair_r(0), - hair_g(0), - hair_b(0), - proportion_x(0), - proportion_y(0), - play_time(0) { } - - + : experience(0), + level(0), + unknown_a2(0), + name_color(0), + extra_model(0), + name_color_checksum(0), + section_id(0), + char_class(0), + v2_flags(0), + version(0), + v1_flags(0), + costume(0), + skin(0), + face(0), + head(0), + hair(0), + hair_r(0), + hair_g(0), + hair_b(0), + proportion_x(0), + proportion_y(0), + play_time(0) {} GuildCardV3::GuildCardV3() noexcept - : player_tag(0), - guild_card_number(0), - present(0), - language(0), - section_id(0), - char_class(0) { } + : player_tag(0), + guild_card_number(0), + present(0), + language(0), + section_id(0), + char_class(0) {} GuildCardBB::GuildCardBB() noexcept - : guild_card_number(0), - present(0), - language(0), - section_id(0), - char_class(0) { } + : guild_card_number(0), + present(0), + language(0), + section_id(0), + char_class(0) {} void GuildCardBB::clear() { this->guild_card_number = 0; @@ -326,8 +320,6 @@ uint32_t GuildCardFileBB::checksum() const { return crc32(this, sizeof(*this)); } - - void PlayerBank::load(const string& filename) { *this = player_files_cache.get_obj_or_load(filename).obj; for (uint32_t x = 0; x < this->num_items; x++) { @@ -342,16 +334,14 @@ void PlayerBank::save(const string& filename, bool save_to_filesystem) const { } } - - //////////////////////////////////////////////////////////////////////////////// ClientGameData::ClientGameData() - : last_play_time_update(0), - guild_card_number(0), - should_update_play_time(false), - bb_player_index(0), - should_save(true) { } + : last_play_time_update(0), + guild_card_number(0), + should_update_play_time(false), + bb_player_index(0), + should_save(true) {} ClientGameData::~ClientGameData() { if (!this->bb_username.empty()) { @@ -461,7 +451,8 @@ void ClientGameData::load_account_data() { player_files_cache.delete_key(filename); data.reset(new SavedAccountDataBB( player_files_cache.get_obj_or_load( - "system/players/default.nsa").obj)); + "system/players/default.nsa") + .obj)); if (data->signature != ACCOUNT_FILE_SIGNATURE) { throw runtime_error("default account data header is incorrect"); } @@ -592,8 +583,6 @@ PlayerBB ClientGameData::export_player_bb() { return ret; } - - void PlayerLobbyDataPC::clear() { this->player_tag = 0; this->guild_card = 0; @@ -638,7 +627,6 @@ void PlayerLobbyDataBB::clear() { this->unknown_a2 = 0; } - //////////////////////////////////////////////////////////////////////////////// PlayerInventoryItem::PlayerInventoryItem() { @@ -646,7 +634,9 @@ PlayerInventoryItem::PlayerInventoryItem() { } PlayerInventoryItem::PlayerInventoryItem(const PlayerBankItem& src) - : present(1), flags(0), data(src.data) { } + : present(1), + flags(0), + data(src.data) {} void PlayerInventoryItem::clear() { this->present = 0x00000000; @@ -659,9 +649,9 @@ PlayerBankItem::PlayerBankItem() { } PlayerBankItem::PlayerBankItem(const PlayerInventoryItem& src) - : data(src.data), - amount(this->data.stack_size()), - show_flags(1) { } + : data(src.data), + amount(this->data.stack_size()), + show_flags(1) {} void PlayerBankItem::clear() { this->data.clear(); @@ -669,15 +659,11 @@ void PlayerBankItem::clear() { this->show_flags = 0; } - - PlayerInventory::PlayerInventory() - : num_items(0), - hp_materials_used(0), - tp_materials_used(0), - language(0) { } - - + : num_items(0), + hp_materials_used(0), + tp_materials_used(0), + language(0) {} // TODO: Eliminate duplication between this function and the parallel function // in PlayerBank diff --git a/src/Player.hh b/src/Player.hh index c572ba05..3a619515 100644 --- a/src/Player.hh +++ b/src/Player.hh @@ -4,18 +4,16 @@ #include #include -#include -#include -#include #include +#include +#include +#include -#include "LevelTable.hh" -#include "ItemData.hh" -#include "Version.hh" -#include "Text.hh" #include "Episode3/DataIndex.hh" - - +#include "ItemData.hh" +#include "LevelTable.hh" +#include "Text.hh" +#include "Version.hh" struct PlayerBankItem; @@ -67,8 +65,6 @@ struct PlayerBank { // 0x12C8 bytes size_t find_item(uint32_t item_id); } __attribute__((packed)); - - struct PendingItemTrade { uint8_t other_client_id; bool confirmed; // true if client has sent a D2 command @@ -81,8 +77,6 @@ struct PendingCardTrade { std::vector> card_to_count; }; - - struct PlayerDispDataBB; struct PlayerDispDataDCPCV3 { // 0xD0 bytes @@ -192,15 +186,13 @@ struct PlayerDispDataBB { PlayerDispDataBB() noexcept; - inline void enforce_v2_limits() { } + inline void enforce_v2_limits() {} PlayerDispDataDCPCV3 to_dcpcv3() const; PlayerDispDataBBPreview to_preview() const; void apply_preview(const PlayerDispDataBBPreview&); void apply_dressing_room(const PlayerDispDataBBPreview&); } __attribute__((packed)); - - // TODO: Is this the same for XB as it is for GC? (This struct is based on the // GC format) struct GuildCardV3 { @@ -212,7 +204,7 @@ struct GuildCardV3 { /* 8D */ uint8_t language; /* 8E */ uint8_t section_id; /* 8F */ uint8_t char_class; - /* 90 */ + /* 90 */ GuildCardV3() noexcept; } __attribute__((packed)); @@ -252,21 +244,19 @@ struct GuildCardFileBB { } __attribute__((packed)); struct KeyAndTeamConfigBB { - parray unknown_a1; // 0000 - parray key_config; // 0114 + parray unknown_a1; // 0000 + parray key_config; // 0114 parray joystick_config; // 0280 - le_uint32_t guild_card_number; // 02B8 - le_uint32_t team_id; // 02BC - le_uint64_t team_info; // 02C0 - le_uint16_t team_privilege_level; // 02C8 - le_uint16_t reserved; // 02CA - ptext team_name; // 02CC - parray team_flag; // 02EC - le_uint32_t team_rewards; // 0AEC + le_uint32_t guild_card_number; // 02B8 + le_uint32_t team_id; // 02BC + le_uint64_t team_info; // 02C0 + le_uint16_t team_privilege_level; // 02C8 + le_uint16_t reserved; // 02CA + ptext team_name; // 02CC + parray team_flag; // 02EC + le_uint32_t team_rewards; // 0AEC } __attribute__((packed)); - - struct PlayerLobbyDataPC { le_uint32_t player_tag = 0; le_uint32_t guild_card = 0; @@ -328,8 +318,6 @@ struct PlayerLobbyDataBB { void clear(); } __attribute__((packed)); - - struct PlayerChallengeDataV3 { le_uint32_t client_id; struct { @@ -365,8 +353,6 @@ struct PlayerChallengeDataBB { parray unknown_a1; } __attribute__((packed)); - - template struct ChoiceSearchConfig { // 0 = enabled, 1 = disabled. Unused for command C3 @@ -378,8 +364,6 @@ struct ChoiceSearchConfig { parray entries; } __attribute__((packed)); - - struct PSOPlayerDataDCPC { // For command 61 PlayerInventory inventory; PlayerDispDataDCPCV3 disp; @@ -423,45 +407,43 @@ struct PSOPlayerDataBB { // For command 61 } __attribute__((packed)); struct PlayerBB { // Used in 00E7 command - PlayerInventory inventory; // 0000-034C; player - PlayerDispDataBB disp; // 034C-04DC; player - parray unknown; // 04DC-04EC; not saved - le_uint32_t option_flags; // 04EC-04F0; account - parray quest_data1; // 04F0-06F8; player - PlayerBank bank; // 06F8-19C0; player - le_uint32_t guild_card_number; // 19C0-19C4; player - ptext name; // 19C4-19F4; player - ptext team_name; // 19F4-1A14; player + PlayerInventory inventory; // 0000-034C; player + PlayerDispDataBB disp; // 034C-04DC; player + parray unknown; // 04DC-04EC; not saved + le_uint32_t option_flags; // 04EC-04F0; account + parray quest_data1; // 04F0-06F8; player + PlayerBank bank; // 06F8-19C0; player + le_uint32_t guild_card_number; // 19C0-19C4; player + ptext name; // 19C4-19F4; player + ptext team_name; // 19F4-1A14; player ptext guild_card_description; // 1A14-1AC4; player - uint8_t reserved1; // 1AC4-1AC5; player - uint8_t reserved2; // 1AC5-1AC6; player - uint8_t section_id; // 1AC6-1AC7; player - uint8_t char_class; // 1AC7-1AC8; player - le_uint32_t unknown3; // 1AC8-1ACC; not saved - parray symbol_chats; // 1ACC-1FAC; account - parray shortcuts; // 1FAC-29EC; account - ptext auto_reply; // 29EC-2B44; player - ptext info_board; // 2B44-2C9C; player - parray unknown5; // 2C9C-2CB8; not saved - parray challenge_data; // 2CB8-2DF8; player - parray tech_menu_config; // 2DF8-2E20; player - parray unknown6; // 2E20-2E4C; not saved - parray quest_data2; // 2E4C-2EA4; player - KeyAndTeamConfigBB key_config; // 2EA4-3994; account + uint8_t reserved1; // 1AC4-1AC5; player + uint8_t reserved2; // 1AC5-1AC6; player + uint8_t section_id; // 1AC6-1AC7; player + uint8_t char_class; // 1AC7-1AC8; player + le_uint32_t unknown3; // 1AC8-1ACC; not saved + parray symbol_chats; // 1ACC-1FAC; account + parray shortcuts; // 1FAC-29EC; account + ptext auto_reply; // 29EC-2B44; player + ptext info_board; // 2B44-2C9C; player + parray unknown5; // 2C9C-2CB8; not saved + parray challenge_data; // 2CB8-2DF8; player + parray tech_menu_config; // 2DF8-2E20; player + parray unknown6; // 2E20-2E4C; not saved + parray quest_data2; // 2E4C-2EA4; player + KeyAndTeamConfigBB key_config; // 2EA4-3994; account } __attribute__((packed)); - - struct SavedPlayerDataBB { // .nsc file format - ptext signature; + ptext signature; PlayerDispDataBBPreview preview; ptext auto_reply; - PlayerBank bank; + PlayerBank bank; parray challenge_data; - PlayerDispDataBB disp; + PlayerDispDataBB disp; ptext guild_card_description; ptext info_board; - PlayerInventory inventory; + PlayerInventory inventory; parray quest_data1; parray quest_data2; parray tech_menu_config; @@ -478,19 +460,17 @@ enum AccountFlag { }; struct SavedAccountDataBB { // .nsa file format - ptext signature; + ptext signature; parray blocked_senders; - GuildCardFileBB guild_cards; - KeyAndTeamConfigBB key_config; - le_uint32_t newserv_flags; - le_uint32_t option_flags; - parray shortcuts; - parray symbol_chats; - ptext team_name; + GuildCardFileBB guild_cards; + KeyAndTeamConfigBB key_config; + le_uint32_t newserv_flags; + le_uint32_t option_flags; + parray shortcuts; + parray symbol_chats; + ptext team_name; } __attribute__((packed)); - - class ClientGameData { private: std::shared_ptr account_data; @@ -547,12 +527,8 @@ public: PlayerBB export_player_bb(); }; - - uint32_t compute_guild_card_checksum(const void* data, size_t size); - - template DestT convert_player_disp_data(const SrcT&) { static_assert(always_false::v, diff --git a/src/Product.cc b/src/Product.cc index 35b8c224..2301d745 100644 --- a/src/Product.cc +++ b/src/Product.cc @@ -1,15 +1,13 @@ #include -#include #include +#include #include #include "PSOEncryption.hh" using namespace std; - - static const uint32_t primes1[] = { 0x65, 0x67, 0x6B, 0x6D, 0x71, 0x7F, 0x83, 0x89, 0x8B, 0x95, 0x97, 0x9D, 0xA3, 0xA7, 0xAD, 0xB3, 0xB5, 0xBF, 0xC1, 0xC5, 0xC7, 0xD3, 0xDF, 0xE3, @@ -1125,8 +1123,6 @@ static bool check_prime3(uint64_t prime3) { return primes3_set[offset]; } - - static char replace_char_forward(char ch) { if (ch >= '0' && ch <= '9') { return "5A76D2C1F0"[ch - '0']; diff --git a/src/Product.hh b/src/Product.hh index 0423e4b8..16ff4727 100644 --- a/src/Product.hh +++ b/src/Product.hh @@ -4,8 +4,6 @@ #include - - bool product_is_valid( const std::string& s, uint8_t domain, uint8_t subdomain = 0xFF); bool product_is_valid_fast( diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 635690ed..2051974f 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -26,18 +26,16 @@ #include #endif -#include "Loggers.hh" #include "ChatCommands.hh" #include "Compression.hh" +#include "Loggers.hh" #include "PSOProtocol.hh" -#include "SendCommands.hh" #include "ReceiveCommands.hh" #include "ReceiveSubcommands.hh" +#include "SendCommands.hh" using namespace std; - - struct HandlerResult { enum class Type { FORWARD = 0, @@ -50,9 +48,13 @@ struct HandlerResult { int32_t new_command; int64_t new_flag; - HandlerResult(Type type) : type(type), new_command(-1), new_flag(-1) { } + HandlerResult(Type type) : type(type), + new_command(-1), + new_flag(-1) {} HandlerResult(Type type, uint16_t new_command, uint32_t new_flag) - : type(type), new_command(new_command), new_flag(new_flag) { } + : type(type), + new_command(new_command), + new_flag(new_flag) {} }; typedef HandlerResult (*on_command_t)( @@ -62,8 +64,6 @@ typedef HandlerResult (*on_command_t)( uint32_t flag, string& data); - - static void forward_command(ProxyServer::LinkedSession& session, bool to_server, uint16_t command, uint32_t flag, string& data, bool print_contents = true) { auto& ch = to_server ? session.server_channel : session.client_channel; @@ -86,8 +86,6 @@ static void check_implemented_subcommand( } } - - // Command handlers. These are called to preprocess or react to specific // commands in either direction. The functions have abbreviated names in order // to make the massive table more readable. The functions' names are, in @@ -148,8 +146,7 @@ static HandlerResult C_G_9E(shared_ptr, le_uint64_t checksum = random_object() & 0x0000FFFFFFFFFFFF; session.server_channel.send(0x96, 0x00, &checksum, sizeof(checksum)); - S_UpdateClientConfig_DC_PC_V3_04 cmd = {{ - 0x00010000, session.license->serial_number, ClientConfig()}}; + S_UpdateClientConfig_DC_PC_V3_04 cmd = {{0x00010000, session.license->serial_number, ClientConfig()}}; session.client_channel.send(0x04, 0x00, &cmd, sizeof(cmd)); return HandlerResult::Type::SUPPRESS; @@ -159,7 +156,6 @@ static HandlerResult C_G_9E(shared_ptr, } } - static HandlerResult S_G_9A(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { if (!session.license || session.options.suppress_remote_login) { @@ -265,7 +261,7 @@ static HandlerResult S_V123P_02_17( return HandlerResult::Type::SUPPRESS; } else if ((session.version == GameVersion::DC) || - (session.version == GameVersion::PC)) { + (session.version == GameVersion::PC)) { if (session.newserv_client_config.cfg.flags & Client::Flag::IS_DC_V1) { if (command == 0x17) { C_LoginV1_DC_PC_V3_90 cmd; @@ -447,9 +443,9 @@ static HandlerResult S_B_03(shared_ptr s, return HandlerResult::Type::SUPPRESS; - // If there's no detector crypt, then the session is new and was linked - // immediately at connect time, and an 03 was not yet sent to the client, so - // we should forward this one. + // If there's no detector crypt, then the session is new and was linked + // immediately at connect time, and an 03 was not yet sent to the client, so + // we should forward this one. } else { // Forward the command to the client before setting up the crypts, so the // client receives the unencrypted data @@ -511,12 +507,12 @@ static HandlerResult S_V123_04(shared_ptr, // init text instead of the port map init text. memcpy(session.remote_client_config_data.data(), had_guild_card_number - ? "t Lobby Server. Copyright SEGA E" - : "t Port Map. Copyright SEGA Enter", + ? "t Lobby Server. Copyright SEGA E" + : "t Port Map. Copyright SEGA Enter", session.remote_client_config_data.bytes()); memcpy(session.remote_client_config_data.data(), &cmd.cfg, min(data.size() - offsetof(S_UpdateClientConfig_DC_PC_V3_04, cfg), - session.remote_client_config_data.bytes())); + session.remote_client_config_data.bytes())); // If the guild card number was not set, pretend (to the server) that this is // the first 04 command the client has received. The client responds with a 96 @@ -912,8 +908,8 @@ static HandlerResult S_6x(shared_ptr, // Unmask any masked Episode 3 commands from the server if ((session.version == GameVersion::GC) && (data.size() > 8) && ((static_cast(data[0]) == 0xB3) || - (static_cast(data[0]) == 0xB4) || - (static_cast(data[0]) == 0xB5))) { + (static_cast(data[0]) == 0xB4) || + (static_cast(data[0]) == 0xB5))) { const auto& header = check_size_t( data, sizeof(G_CardBattleCommandHeader), 0xFFFF); if (header.mask_key) { @@ -951,8 +947,8 @@ static HandlerResult S_6x(shared_ptr, } } else if ((data[0] == 0x60) && - session.next_drop_item.data.data1d[0] && - (session.version != GameVersion::BB)) { + session.next_drop_item.data.data1d[0] && + (session.version != GameVersion::BB)) { const auto& cmd = check_size_t(data, sizeof(G_EnemyDropItemRequest_DC_6x60), sizeof(G_EnemyDropItemRequest_PC_V3_BB_6x60)); @@ -964,13 +960,13 @@ static HandlerResult S_6x(shared_ptr, session.next_drop_item.clear(); return HandlerResult::Type::SUPPRESS; - // Note: This static_cast is required to make compilers not complain that - // the comparison is always false (which even happens in some environments - // if we use -0x5E... apparently char is unsigned on some systems, or - // std::string's char_type isn't char??) + // Note: This static_cast is required to make compilers not complain that + // the comparison is always false (which even happens in some environments + // if we use -0x5E... apparently char is unsigned on some systems, or + // std::string's char_type isn't char??) } else if ((static_cast(data[0]) == 0xA2) && - session.next_drop_item.data.data1d[0] && - (session.version != GameVersion::BB)) { + session.next_drop_item.data.data1d[0] && + (session.version != GameVersion::BB)) { const auto& cmd = check_size_t(data); session.next_drop_item.data.id = session.next_item_id++; send_drop_item(session.server_channel, session.next_drop_item.data, @@ -981,8 +977,8 @@ static HandlerResult S_6x(shared_ptr, return HandlerResult::Type::SUPPRESS; } else if ((static_cast(data[0]) == 0xB5) && - (session.version == GameVersion::GC) && - (data.size() > 4)) { + (session.version == GameVersion::GC) && + (data.size() > 4)) { if (data[4] == 0x1A) { return HandlerResult::Type::SUPPRESS; } else if (data[4] == 0x36) { @@ -1586,7 +1582,6 @@ constexpr on_command_t C_DGX_81 = &C_81; constexpr on_command_t C_P_81 = &C_81; constexpr on_command_t C_B_81 = &C_81; - template void C_6x_movement(ProxyServer::LinkedSession& session, const string& data) { const auto& cmd = check_size_t(data); @@ -1676,10 +1671,9 @@ static HandlerResult C_V123_A0_A1(shared_ptr, return HandlerResult::Type::SUPPRESS; } - - // [command][version][is_client] static on_command_t handlers[0x100][6][2] = { + // clang-format off // CMD S-PATCH C-PATCH S-DC C-DC S-PC C-PC S-GC C-GC S-XB C-XB S-BB C-BB /* 00 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 01 */ {{S_invalid, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {S_invalid, nullptr}}, @@ -1945,6 +1939,7 @@ static on_command_t handlers[0x100][6][2] = { /* FE */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* FF */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, // CMD S-PATCH C-PATCH S-DC C-DC S-PC C-PC S-GC C-GC S-XB C-XB S-BB C-BB + // clang-format on }; static on_command_t get_handler(GameVersion version, bool from_server, uint8_t command) { diff --git a/src/ProxyCommands.hh b/src/ProxyCommands.hh index c4045f99..e3b1fa5b 100644 --- a/src/ProxyCommands.hh +++ b/src/ProxyCommands.hh @@ -4,10 +4,8 @@ #include -#include "ServerState.hh" #include "ProxyServer.hh" - - +#include "ServerState.hh" void on_proxy_command( std::shared_ptr s, diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index a9b2c0d1..651ddf60 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -25,23 +25,21 @@ #include "Loggers.hh" #include "PSOProtocol.hh" -#include "SendCommands.hh" +#include "ProxyCommands.hh" #include "ReceiveCommands.hh" #include "ReceiveSubcommands.hh" -#include "ProxyCommands.hh" +#include "SendCommands.hh" using namespace std; using namespace std::placeholders; - - ProxyServer::ProxyServer( shared_ptr base, shared_ptr state) - : base(base), - destroy_sessions_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &ProxyServer::dispatch_destroy_sessions, this), event_free), - state(state), - next_unlicensed_session_id(0xFF00000000000001) { } + : base(base), + destroy_sessions_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &ProxyServer::dispatch_destroy_sessions, this), event_free), + state(state), + next_unlicensed_session_id(0xFF00000000000001) {} void ProxyServer::listen(uint16_t port, GameVersion version, const struct sockaddr_storage* default_destination) { @@ -55,12 +53,12 @@ ProxyServer::ListeningSocket::ListeningSocket( uint16_t port, GameVersion version, const struct sockaddr_storage* default_destination) - : server(server), - log(string_printf("[ProxyServer:ListeningSocket:%hu] ", port), proxy_server_log.min_level), - port(port), - fd(::listen("", port, SOMAXCONN)), - listener(nullptr, evconnlistener_free), - version(version) { + : server(server), + log(string_printf("[ProxyServer:ListeningSocket:%hu] ", port), proxy_server_log.min_level), + port(port), + fd(::listen("", port, SOMAXCONN)), + listener(nullptr, evconnlistener_free), + version(version) { if (!this->fd.is_open()) { throw runtime_error("cannot listen on port"); } @@ -114,8 +112,6 @@ void ProxyServer::ListeningSocket::on_listen_error() { event_base_loopexit(this->server->base.get(), nullptr); } - - void ProxyServer::connect_client(struct bufferevent* bev, uint16_t server_port) { // Look up the listening socket for the given port, and use that game version. // We don't support default-destination proxying for virtual connections (yet) @@ -135,8 +131,6 @@ void ProxyServer::connect_client(struct bufferevent* bev, uint16_t server_port) this->on_client_connect(bev, server_port, version, nullptr); } - - void ProxyServer::on_client_connect( struct bufferevent* bev, uint16_t listen_port, @@ -151,8 +145,7 @@ void ProxyServer::on_client_connect( this->next_unlicensed_session_id = 0xFF00000000000001; } - auto emplace_ret = this->id_to_session.emplace(session_id, new LinkedSession( - this, session_id, listen_port, version, *default_destination)); + auto emplace_ret = this->id_to_session.emplace(session_id, new LinkedSession(this, session_id, listen_port, version, *default_destination)); if (!emplace_ret.second) { throw logic_error("linked session already exists for unlicensed client"); } @@ -162,12 +155,11 @@ void ProxyServer::on_client_connect( Channel ch(bev, version, nullptr, nullptr, session.get(), "", TerminalFormat::FG_YELLOW, TerminalFormat::FG_GREEN); session->resume(move(ch)); - // If no default destination exists, or the client is not a patch client, - // create an unlinked session - we'll have to get the destination from the - // client's config, which we'll get via a 9E command soon. + // If no default destination exists, or the client is not a patch client, + // create an unlinked session - we'll have to get the destination from the + // client's config, which we'll get via a 9E command soon. } else { - auto emplace_ret = this->bev_to_unlinked_session.emplace(bev, new UnlinkedSession( - this, bev, listen_port, version)); + auto emplace_ret = this->bev_to_unlinked_session.emplace(bev, new UnlinkedSession(this, bev, listen_port, version)); if (!emplace_ret.second) { throw logic_error("stale unlinked session exists"); } @@ -227,26 +219,24 @@ void ProxyServer::on_client_connect( } } - - ProxyServer::UnlinkedSession::UnlinkedSession( ProxyServer* server, struct bufferevent* bev, uint16_t local_port, GameVersion version) - : server(server), - log(string_printf("[ProxyServer:UnlinkedSession:%p] ", bev), proxy_server_log.min_level), - channel( - bev, - version, - ProxyServer::UnlinkedSession::on_input, - ProxyServer::UnlinkedSession::on_error, - this, - string_printf("UnlinkedSession:%p", bev), - TerminalFormat::FG_YELLOW, - TerminalFormat::FG_GREEN), - local_port(local_port), - version(version) { + : server(server), + log(string_printf("[ProxyServer:UnlinkedSession:%p] ", bev), proxy_server_log.min_level), + channel( + bev, + version, + ProxyServer::UnlinkedSession::on_input, + ProxyServer::UnlinkedSession::on_error, + this, + string_printf("UnlinkedSession:%p", bev), + TerminalFormat::FG_YELLOW, + TerminalFormat::FG_GREEN), + local_port(local_port), + version(version) { memset(&this->next_destination, 0, sizeof(this->next_destination)); } @@ -440,51 +430,50 @@ void ProxyServer::UnlinkedSession::on_error(Channel& ch, short events) { } } - - ProxyServer::LinkedSession::LinkedSession( ProxyServer* server, uint64_t id, uint16_t local_port, GameVersion version) - : server(server), - id(id), - log(string_printf("[ProxyServer:LinkedSession:%08" PRIX64 "] ", this->id), proxy_server_log.min_level), - timeout_event(event_new(this->server->base.get(), -1, EV_TIMEOUT, - &LinkedSession::dispatch_on_timeout, this), event_free), - license(nullptr), - client_channel( - version, - nullptr, - nullptr, - this, - string_printf("LinkedSession:%08" PRIX64 ":client", this->id), - TerminalFormat::FG_YELLOW, - TerminalFormat::FG_GREEN), - server_channel( - version, - nullptr, - nullptr, - this, - string_printf("LinkedSession:%08" PRIX64 ":server", this->id), - TerminalFormat::FG_YELLOW, - TerminalFormat::FG_RED), - local_port(local_port), - disconnect_action(DisconnectAction::LONG_TIMEOUT), - remote_ip_crc(0), - enable_remote_ip_crc_patch(false), - version(version), - sub_version(0), // This is set during resume() - language(1), // Default = English. This is also set during resume() - remote_guild_card_number(-1), - next_item_id(0x0F000000), - lobby_players(12), - lobby_client_id(0), - leader_client_id(0), - area(0), - x(0.0), - z(0.0), - is_in_game(false) { + : server(server), + id(id), + log(string_printf("[ProxyServer:LinkedSession:%08" PRIX64 "] ", this->id), proxy_server_log.min_level), + timeout_event(event_new(this->server->base.get(), -1, EV_TIMEOUT, + &LinkedSession::dispatch_on_timeout, this), + event_free), + license(nullptr), + client_channel( + version, + nullptr, + nullptr, + this, + string_printf("LinkedSession:%08" PRIX64 ":client", this->id), + TerminalFormat::FG_YELLOW, + TerminalFormat::FG_GREEN), + server_channel( + version, + nullptr, + nullptr, + this, + string_printf("LinkedSession:%08" PRIX64 ":server", this->id), + TerminalFormat::FG_YELLOW, + TerminalFormat::FG_RED), + local_port(local_port), + disconnect_action(DisconnectAction::LONG_TIMEOUT), + remote_ip_crc(0), + enable_remote_ip_crc_patch(false), + version(version), + sub_version(0), // This is set during resume() + language(1), // Default = English. This is also set during resume() + remote_guild_card_number(-1), + next_item_id(0x0F000000), + lobby_players(12), + lobby_client_id(0), + leader_client_id(0), + area(0), + x(0.0), + z(0.0), + is_in_game(false) { this->last_switch_enabled_command.header.subcommand = 0; memset(this->prev_server_command_bytes, 0, sizeof(this->prev_server_command_bytes)); } @@ -495,7 +484,7 @@ ProxyServer::LinkedSession::LinkedSession( GameVersion version, shared_ptr license, const ClientConfigBB& newserv_client_config) - : LinkedSession(server, license->serial_number, local_port, version) { + : LinkedSession(server, license->serial_number, local_port, version) { this->license = license; this->newserv_client_config = newserv_client_config; memset(&this->next_destination, 0, sizeof(this->next_destination)); @@ -511,7 +500,7 @@ ProxyServer::LinkedSession::LinkedSession( GameVersion version, std::shared_ptr license, const struct sockaddr_storage& next_destination) - : LinkedSession(server, license->serial_number, local_port, version) { + : LinkedSession(server, license->serial_number, local_port, version) { this->license = license; this->next_destination = next_destination; } @@ -522,7 +511,7 @@ ProxyServer::LinkedSession::LinkedSession( uint16_t local_port, GameVersion version, const struct sockaddr_storage& destination) - : LinkedSession(server, id, local_port, version) { + : LinkedSession(server, id, local_port, version) { this->next_destination = destination; } @@ -594,7 +583,7 @@ void ProxyServer::LinkedSession::connect() { this->server_channel.set_bufferevent(bufferevent_socket_new( this->server->base.get(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS)); if (bufferevent_socket_connect(this->server_channel.bev.get(), - reinterpret_cast(dest_sin), sizeof(*dest_sin)) != 0) { + reinterpret_cast(dest_sin), sizeof(*dest_sin)) != 0) { throw runtime_error(string_printf("failed to connect (%d)", EVUTIL_SOCKET_ERROR())); } @@ -606,35 +595,27 @@ void ProxyServer::LinkedSession::connect() { event_del(this->timeout_event.get()); } - - ProxyServer::LinkedSession::SavingFile::SavingFile( const string& basename, const string& output_filename, uint32_t remaining_bytes) - : basename(basename), - output_filename(output_filename), - remaining_bytes(remaining_bytes) { + : basename(basename), + output_filename(output_filename), + remaining_bytes(remaining_bytes) { if (!this->output_filename.empty()) { this->f = fopen_unique(this->output_filename, "wb"); } } - - void ProxyServer::LinkedSession::dispatch_on_timeout( evutil_socket_t, short, void* ctx) { reinterpret_cast(ctx)->on_timeout(); } - - void ProxyServer::LinkedSession::on_timeout() { this->server->delete_session(this->id); } - - void ProxyServer::LinkedSession::on_error(Channel& ch, short events) { auto* session = reinterpret_cast(ch.context_obj); bool is_server_stream = (&ch == &session->server_channel); @@ -643,11 +624,9 @@ void ProxyServer::LinkedSession::on_error(Channel& ch, short events) { session->log.info("%s channel connected", is_server_stream ? "Server" : "Client"); if (is_server_stream && (session->options.override_lobby_event >= 0) && - ( - ((session->version == GameVersion::GC) && !(session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)) || - (session->version == GameVersion::XB) || - (session->version == GameVersion::BB) - )) { + (((session->version == GameVersion::GC) && !(session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)) || + (session->version == GameVersion::XB) || + (session->version == GameVersion::BB))) { session->client_channel.send(0xDA, session->options.override_lobby_event); } } @@ -702,15 +681,11 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) string encoded_name = encode_sjis(this->server->state->name); if (this->is_in_game) { - send_ship_info(this->client_channel, decode_sjis(string_printf( - "You cannot return\nto $C6%s$C7\nwhile in a game.\n\n%s", - encoded_name.c_str(), error_message ? error_message : ""))); + send_ship_info(this->client_channel, decode_sjis(string_printf("You cannot return\nto $C6%s$C7\nwhile in a game.\n\n%s", encoded_name.c_str(), error_message ? error_message : ""))); this->disconnect(); } else { - send_ship_info(this->client_channel, decode_sjis(string_printf( - "You\'ve returned to\n\tC6%s$C7\n\n%s", encoded_name.c_str(), - error_message ? error_message : ""))); + send_ship_info(this->client_channel, decode_sjis(string_printf("You\'ve returned to\n\tC6%s$C7\n\n%s", encoded_name.c_str(), error_message ? error_message : ""))); // Restore newserv_client_config, so the login server gets the client flags S_UpdateClientConfig_DC_PC_V3_04 update_client_config_cmd; @@ -722,8 +697,7 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) const auto& port_name = version_to_login_port_name.at(static_cast( this->version)); - S_Reconnect_19 reconnect_cmd = {{ - 0, this->server->state->name_to_port_config.at(port_name)->port, 0}}; + S_Reconnect_19 reconnect_cmd = {{0, this->server->state->name_to_port_config.at(port_name)->port, 0}}; // If the client is on a virtual connection, we can use any address // here and they should be able to connect back to the game server. If @@ -781,8 +755,6 @@ bool ProxyServer::LinkedSession::is_connected() const { return (this->server_channel.connected() && this->client_channel.connected()); } - - void ProxyServer::LinkedSession::on_input(Channel& ch, uint16_t command, uint32_t flag, std::string& data) { auto* session = reinterpret_cast(ch.context_obj); bool is_server_stream = (&ch == &session->server_channel); diff --git a/src/ProxyServer.hh b/src/ProxyServer.hh index ad70f441..5fdaa2af 100644 --- a/src/ProxyServer.hh +++ b/src/ProxyServer.hh @@ -3,21 +3,19 @@ #include #include -#include -#include -#include #include -#include -#include +#include #include #include +#include +#include +#include +#include #include "PSOEncryption.hh" #include "PSOProtocol.hh" #include "ServerState.hh" - - class ProxyServer { public: ProxyServer() = delete; @@ -38,7 +36,7 @@ public: uint64_t id; PrefixedLogger log; - std::unique_ptr timeout_event; + std::unique_ptr timeout_event; std::shared_ptr license; @@ -80,7 +78,9 @@ public: std::string name; uint8_t section_id; uint8_t char_class; - LobbyPlayer() : guild_card_number(0), section_id(0), char_class(0) { } + LobbyPlayer() : guild_card_number(0), + section_id(0), + char_class(0) {} }; std::vector lobby_players; size_t lobby_client_id; @@ -163,10 +163,10 @@ public: std::shared_ptr get_session(); std::shared_ptr get_session_by_name(const std::string& name); std::shared_ptr create_licensed_session( - std::shared_ptr l, - uint16_t local_port, - GameVersion version, - const ClientConfigBB& newserv_client_config); + std::shared_ptr l, + uint16_t local_port, + GameVersion version, + const ClientConfigBB& newserv_client_config); void delete_session(uint64_t id); void delete_session(struct bufferevent* bev); @@ -179,7 +179,7 @@ private: PrefixedLogger log; uint16_t port; scoped_fd fd; - std::unique_ptr listener; + std::unique_ptr listener; GameVersion version; struct sockaddr_storage default_destination; @@ -190,7 +190,7 @@ private: const struct sockaddr_storage* default_destination); static void dispatch_on_listen_accept(struct evconnlistener* listener, - evutil_socket_t fd, struct sockaddr *address, int socklen, void* ctx); + evutil_socket_t fd, struct sockaddr* address, int socklen, void* ctx); static void dispatch_on_listen_error(struct evconnlistener* listener, void* ctx); void on_listen_accept(int fd); void on_listen_error(); diff --git a/src/Quest.cc b/src/Quest.cc index 6ac2d65e..0bf4d668 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -2,26 +2,24 @@ #include #include -#include -#include -#include #include +#include #include #include #include #include +#include +#include -#include "Loggers.hh" -#include "SaveFileFormats.hh" #include "CommandFormats.hh" #include "Compression.hh" +#include "Loggers.hh" #include "PSOEncryption.hh" +#include "SaveFileFormats.hh" #include "Text.hh" using namespace std; - - // GCI decoding logic template @@ -38,8 +36,10 @@ struct PSOMemCardDLQFileEncryptedHeader { // Data follows here. } __attribute__((packed)); -struct PSOVMSDLQFileEncryptedHeader : PSOMemCardDLQFileEncryptedHeader { } __attribute__((packed)); -struct PSOGCIDLQFileEncryptedHeader : PSOMemCardDLQFileEncryptedHeader { } __attribute__((packed)); +struct PSOVMSDLQFileEncryptedHeader : PSOMemCardDLQFileEncryptedHeader { +} __attribute__((packed)); +struct PSOGCIDLQFileEncryptedHeader : PSOMemCardDLQFileEncryptedHeader { +} __attribute__((packed)); template string decrypt_gci_or_vms_v2_download_quest_data_section( @@ -78,9 +78,7 @@ string decrypt_gci_or_vms_v2_download_quest_data_section( // Unlike the above rounds, round 3 is always little-endian (it corresponds to // the round of encryption done on the server before sending the file to the // client in the first place) - PSOV2Encryption(header->round3_seed).decrypt( - decrypted.data() + sizeof(HeaderT), - decrypted.size() - sizeof(HeaderT)); + PSOV2Encryption(header->round3_seed).decrypt(decrypted.data() + sizeof(HeaderT), decrypted.size() - sizeof(HeaderT)); decrypted.resize(orig_size); // Some download quest GCI files have decompressed_size fields that are 8 @@ -136,7 +134,8 @@ string find_seed_and_decrypt_gci_or_vms_v2_download_quest_data_section( } catch (const runtime_error&) { return false; } - }, 0, 0x100000000, num_threads); + }, + 0, 0x100000000, num_threads); if (!result.empty() && (result_seed < 0x100000000)) { static_game_data_log.info("Found seed %08" PRIX64, result_seed); @@ -146,8 +145,6 @@ string find_seed_and_decrypt_gci_or_vms_v2_download_quest_data_section( } } - - struct PSOVMSFileHeader { ptext short_desc; // "PSO/DOWNLOAD " or "PSOV2/DOWNLOAD " ptext long_desc; // Usually quest name @@ -187,19 +184,15 @@ struct PSOVMSFileHeader { } } __attribute__((packed)); - - struct PSODownloadQuestHeader { le_uint32_t size; le_uint32_t encryption_seed; } __attribute__((packed)); - - bool category_is_mode(QuestCategory category) { return (category == QuestCategory::BATTLE) || - (category == QuestCategory::CHALLENGE) || - (category == QuestCategory::EPISODE_3); + (category == QuestCategory::CHALLENGE) || + (category == QuestCategory::EPISODE_3); } const char* name_for_category(QuestCategory category) { @@ -237,8 +230,6 @@ const char* name_for_category(QuestCategory category) { } } - - struct PSOQuestHeaderDC { // Same format for DC v1 and v2, thankfully uint32_t start_offset; uint32_t unknown_offset1; @@ -297,18 +288,16 @@ struct PSOQuestHeaderBB { ptext long_description; } __attribute__((packed)); - - Quest::Quest(const string& bin_filename) - : internal_id(-1), - menu_item_id(0), - category(QuestCategory::UNKNOWN), - episode(Episode::NONE), - is_dcv1(false), - joinable(false), - file_format(FileFormat::BIN_DAT), - has_mnm_extension(false), - is_dlq_encoded(false) { + : internal_id(-1), + menu_item_id(0), + category(QuestCategory::UNKNOWN), + episode(Episode::NONE), + is_dcv1(false), + joinable(false), + file_format(FileFormat::BIN_DAT), + has_mnm_extension(false), + is_dlq_encoded(false) { if (ends_with(bin_filename, ".bin.gci") || ends_with(bin_filename, ".mnm.gci")) { this->file_format = FileFormat::BIN_DAT_GCI; @@ -383,30 +372,30 @@ Quest::Quest(const string& bin_filename) // Get the category from the second token if needed if (this->category == QuestCategory::UNKNOWN) { static const unordered_map name_to_category({ - {"ret", QuestCategory::RETRIEVAL}, - {"ext", QuestCategory::EXTERMINATION}, - {"evt", QuestCategory::EVENT}, - {"shp", QuestCategory::SHOP}, - {"vr", QuestCategory::VR}, - {"twr", QuestCategory::TOWER}, - // Note: This will be overwritten later for Episode 2 & 4 quests - we - // haven't parsed the episode number from the quest script yet - {"gov", QuestCategory::GOVERNMENT_EPISODE_1}, - {"dl", QuestCategory::DOWNLOAD}, - {"1p", QuestCategory::SOLO}, + {"ret", QuestCategory::RETRIEVAL}, + {"ext", QuestCategory::EXTERMINATION}, + {"evt", QuestCategory::EVENT}, + {"shp", QuestCategory::SHOP}, + {"vr", QuestCategory::VR}, + {"twr", QuestCategory::TOWER}, + // Note: This will be overwritten later for Episode 2 & 4 quests - we + // haven't parsed the episode number from the quest script yet + {"gov", QuestCategory::GOVERNMENT_EPISODE_1}, + {"dl", QuestCategory::DOWNLOAD}, + {"1p", QuestCategory::SOLO}, }); this->category = name_to_category.at(tokens[1]); tokens.erase(tokens.begin() + 1); } static const unordered_map name_to_version({ - {"d1", GameVersion::DC}, - {"dc", GameVersion::DC}, - {"pc", GameVersion::PC}, - {"gc", GameVersion::GC}, - {"gc3", GameVersion::GC}, - {"xb", GameVersion::XB}, - {"bb", GameVersion::BB}, + {"d1", GameVersion::DC}, + {"dc", GameVersion::DC}, + {"pc", GameVersion::PC}, + {"gc", GameVersion::GC}, + {"gc3", GameVersion::GC}, + {"xb", GameVersion::XB}, + {"bb", GameVersion::BB}, }); this->version = name_to_version.at(tokens[1]); @@ -705,7 +694,8 @@ string Quest::decode_vms( const void* data_section = r.getv(header.data_size); try { return decrypt_vms_v1_data_section(data_section, header.data_size); - } catch (const exception& e) { } + } catch (const exception& e) { + } if (known_seed >= 0) { return decrypt_gci_or_vms_v2_download_quest_data_section( @@ -973,8 +963,6 @@ string Quest::export_qst(GameVersion version) const { return move(w.str()); } - - QuestIndex::QuestIndex(const string& directory) : directory(directory) { auto filename_set = list_directory(this->directory); vector filenames(filename_set.begin(), filename_set.end()); @@ -1004,7 +992,8 @@ QuestIndex::QuestIndex(const string& directory) : directory(directory) { q->menu_item_id = next_menu_item_id++; string ascii_name = encode_sjis(q->name); if (!this->version_menu_item_id_to_quest.emplace( - make_pair(q->version, q->menu_item_id), q).second) { + make_pair(q->version, q->menu_item_id), q) + .second) { throw logic_error("duplicate quest menu item id"); } static_game_data_log.info("Indexed quest %s (%s => %s-%" PRId64 " (%" PRIu32 "), %s, %s, joinable=%s, dcv1=%s)", @@ -1050,8 +1039,6 @@ vector> QuestIndex::filter( return ret; } - - static string create_download_quest_file(const string& compressed_data, size_t decompressed_size, uint32_t encryption_seed = 0) { // Download quest files are like normal (PRS-compressed) quest files, but they diff --git a/src/Quest.hh b/src/Quest.hh index 8249f42c..12affdc0 100644 --- a/src/Quest.hh +++ b/src/Quest.hh @@ -10,8 +10,6 @@ #include "StaticGameData.hh" #include "Version.hh" - - enum class QuestCategory { UNKNOWN = -1, RETRIEVAL = 0, @@ -33,8 +31,6 @@ enum class QuestCategory { bool category_is_mode(QuestCategory category); const char* name_for_category(QuestCategory category); - - class Quest { public: enum class FileFormat { @@ -107,5 +103,5 @@ struct QuestIndex { std::shared_ptr get(GameVersion version, uint32_t id) const; std::shared_ptr get_gba(const std::string& name) const; std::vector> filter(GameVersion version, - bool is_dcv1, QuestCategory category) const; + bool is_dcv1, QuestCategory category) const; }; diff --git a/src/RareItemSet.cc b/src/RareItemSet.cc index 05a34aa4..0946c797 100644 --- a/src/RareItemSet.cc +++ b/src/RareItemSet.cc @@ -7,8 +7,6 @@ using namespace std; - - uint32_t RareItemSet::expand_rate(uint8_t pc) { int8_t shift = ((pc >> 3) & 0x1F) - 4; if (shift < 0) { @@ -21,10 +19,8 @@ bool RareItemSet::sample(mt19937& random, uint8_t pc) { return (random() < RareItemSet::expand_rate(pc)); } - - GSLRareItemSet::GSLRareItemSet(shared_ptr data, bool is_big_endian) - : gsl(data, is_big_endian) { } + : gsl(data, is_big_endian) {} const GSLRareItemSet::Table& GSLRareItemSet::get_table( Episode episode, GameMode mode, uint8_t difficulty, uint8_t secid) const { @@ -40,10 +36,10 @@ const GSLRareItemSet::Table& GSLRareItemSet::get_table( } string filename = string_printf("ItemRT%s%s%c%1d.rel", - ((mode == GameMode::CHALLENGE) ? "c" : ""), - ((episode == Episode::EP2) ? "l" : ""), - tolower(abbreviation_for_difficulty(difficulty)), // One of "nhvu" - secid); + ((mode == GameMode::CHALLENGE) ? "c" : ""), + ((episode == Episode::EP2) ? "l" : ""), + tolower(abbreviation_for_difficulty(difficulty)), // One of "nhvu" + secid); auto entry = this->gsl.get(filename); if (entry.second < sizeof(Table)) { throw runtime_error(string_printf("table %s is too small", filename.c_str())); @@ -51,8 +47,6 @@ const GSLRareItemSet::Table& GSLRareItemSet::get_table( return *reinterpret_cast(entry.first); } - - RELRareItemSet::RELRareItemSet(shared_ptr data) : data(data) { if (this->data->size() != sizeof(Table) * 10 * 4 * 3) { throw runtime_error("data file size is incorrect"); diff --git a/src/RareItemSet.hh b/src/RareItemSet.hh index 166de568..262453a2 100644 --- a/src/RareItemSet.hh +++ b/src/RareItemSet.hh @@ -3,13 +3,11 @@ #include #include -#include #include +#include -#include "StaticGameData.hh" #include "GSLArchive.hh" - - +#include "StaticGameData.hh" class RareItemSet { public: @@ -52,8 +50,6 @@ protected: RareItemSet() = default; }; - - class GSLRareItemSet : public RareItemSet { public: GSLRareItemSet(std::shared_ptr data, bool is_big_endian); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 56d298eb..67c3caae 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -16,8 +16,8 @@ #include "FileContentsCache.hh" #include "ItemCreator.hh" #include "Loggers.hh" -#include "ProxyServer.hh" #include "PSOProtocol.hh" +#include "ProxyServer.hh" #include "ReceiveSubcommands.hh" #include "SendCommands.hh" #include "StaticGameData.hh" @@ -25,68 +25,64 @@ using namespace std; - - const char* BATTLE_TABLE_DISCONNECT_HOOK_NAME = "battle_table_state"; const char* QUEST_BARRIER_DISCONNECT_HOOK_NAME = "quest_barrier"; const char* CARD_AUCTION_DISCONNECT_HOOK_NAME = "card_auction"; const char* ADD_NEXT_CLIENT_DISCONNECT_HOOK_NAME = "add_next_game_client"; - - vector quest_categories_menu({ - MenuItem(static_cast(QuestCategory::RETRIEVAL), u"Retrieval", u"$E$C6Quests that involve\nretrieving an object", 0), - MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), - MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), - MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), - MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), - MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::RETRIEVAL), u"Retrieval", u"$E$C6Quests that involve\nretrieving an object", 0), + MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), + MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), + MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), + MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), }); vector quest_battle_menu({ - MenuItem(static_cast(QuestCategory::BATTLE), u"Battle", u"$E$C6Battle mode rule\nsets", 0), + MenuItem(static_cast(QuestCategory::BATTLE), u"Battle", u"$E$C6Battle mode rule\nsets", 0), }); vector quest_challenge_menu({ - MenuItem(static_cast(QuestCategory::CHALLENGE), u"Challenge", u"$E$C6Challenge mode\nquests", 0), + MenuItem(static_cast(QuestCategory::CHALLENGE), u"Challenge", u"$E$C6Challenge mode\nquests", 0), }); vector quest_solo_menu({ - MenuItem(static_cast(QuestCategory::SOLO), u"Solo Quests", u"$E$C6Quests that require\na single player", 0), + MenuItem(static_cast(QuestCategory::SOLO), u"Solo Quests", u"$E$C6Quests that require\na single player", 0), }); vector quest_government_menu({ - MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_1), u"Hero in Red",u"$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline", 0), - MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_2), u"The Military's Hero",u"$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline", 0), - MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_4), u"The Meteor Impact Incident", u"$E$C6Quests that follow\nthe Episode 4\nstoryline", 0), + MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_1), u"Hero in Red", u"$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline", 0), + MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_2), u"The Military's Hero", u"$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline", 0), + MenuItem(static_cast(QuestCategory::GOVERNMENT_EPISODE_4), u"The Meteor Impact Incident", u"$E$C6Quests that follow\nthe Episode 4\nstoryline", 0), }); vector quest_download_menu({ - MenuItem(static_cast(QuestCategory::RETRIEVAL), u"Retrieval", u"$E$C6Quests that involve\nretrieving an object", 0), - MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), - MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), - MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), - MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), - MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), - MenuItem(static_cast(QuestCategory::DOWNLOAD), u"Download", u"$E$C6Quests to download\nto your Memory Card", 0), + MenuItem(static_cast(QuestCategory::RETRIEVAL), u"Retrieval", u"$E$C6Quests that involve\nretrieving an object", 0), + MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), + MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), + MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), + MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::DOWNLOAD), u"Download", u"$E$C6Quests to download\nto your Memory Card", 0), }); static const unordered_map proxy_options_menu_descriptions({ - {ProxyOptionsMenuItemID::GO_BACK, u"Return to the\nproxy menu"}, - {ProxyOptionsMenuItemID::CHAT_COMMANDS, u"Enable chat\ncommands"}, - {ProxyOptionsMenuItemID::CHAT_FILTER, u"Enable escape\nsequences in\nchat messages\nand info board"}, - {ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, u"Show a message\nwhen other players\njoin or leave"}, - {ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"}, - {ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"}, - {ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"}, - {ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, u"Fix Meseta value\nat 1,000,000"}, - {ProxyOptionsMenuItemID::BLOCK_EVENTS, u"Disable seasonal\nevents in the lobby\nand in games"}, - {ProxyOptionsMenuItemID::BLOCK_PATCHES, u"Disable patches sent\nby the remote server"}, - {ProxyOptionsMenuItemID::SAVE_FILES, u"Save local copies of\nfiles from the\nremote server\n(quests, etc.)"}, - {ProxyOptionsMenuItemID::RED_NAME, u"Set your name\ncolor to red"}, - {ProxyOptionsMenuItemID::BLANK_NAME, u"Suppress your\ncharacter name\nduring login"}, - {ProxyOptionsMenuItemID::SUPPRESS_LOGIN, u"Use an alternate\nlogin sequence"}, - {ProxyOptionsMenuItemID::SKIP_CARD, u"Use an alternate\nvalue for your initial\nGuild Card"}, + {ProxyOptionsMenuItemID::GO_BACK, u"Return to the\nproxy menu"}, + {ProxyOptionsMenuItemID::CHAT_COMMANDS, u"Enable chat\ncommands"}, + {ProxyOptionsMenuItemID::CHAT_FILTER, u"Enable escape\nsequences in\nchat messages\nand info board"}, + {ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, u"Show a message\nwhen other players\njoin or leave"}, + {ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"}, + {ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"}, + {ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"}, + {ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, u"Fix Meseta value\nat 1,000,000"}, + {ProxyOptionsMenuItemID::BLOCK_EVENTS, u"Disable seasonal\nevents in the lobby\nand in games"}, + {ProxyOptionsMenuItemID::BLOCK_PATCHES, u"Disable patches sent\nby the remote server"}, + {ProxyOptionsMenuItemID::SAVE_FILES, u"Save local copies of\nfiles from the\nremote server\n(quests, etc.)"}, + {ProxyOptionsMenuItemID::RED_NAME, u"Set your name\ncolor to red"}, + {ProxyOptionsMenuItemID::BLANK_NAME, u"Suppress your\ncharacter name\nduring login"}, + {ProxyOptionsMenuItemID::SUPPRESS_LOGIN, u"Use an alternate\nlogin sequence"}, + {ProxyOptionsMenuItemID::SKIP_CARD, u"Use an alternate\nvalue for your initial\nGuild Card"}, }); static vector proxy_options_menu_for_client( @@ -130,12 +126,10 @@ static vector proxy_options_menu_for_client( return ret; } - - static void send_client_to_lobby_server(shared_ptr s, shared_ptr c) { const auto& port_name = version_to_lobby_port_name.at(static_cast(c->version())); send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); + s->name_to_port_config.at(port_name)->port); } static void send_client_to_proxy_server(shared_ptr s, shared_ptr c) { @@ -157,7 +151,7 @@ static void send_client_to_proxy_server(shared_ptr s, shared_ptr s, shared_ptr c) { send_menu(c, u"Proxy server", MenuID::PROXY_DESTINATIONS, - s->proxy_destinations_menu_for_version(c->version())); + s->proxy_destinations_menu_for_version(c->version())); } static bool send_enable_send_function_call_if_applicable( @@ -174,8 +168,6 @@ static bool send_enable_send_function_call_if_applicable( return false; } - - //////////////////////////////////////////////////////////////////////////////// void on_connect(std::shared_ptr s, std::shared_ptr c) { @@ -205,7 +197,7 @@ void on_connect(std::shared_ptr s, std::shared_ptr c) { default: c->log.error("Unimplemented behavior: %" PRId64, - static_cast(c->server_behavior)); + static_cast(c->server_behavior)); } } @@ -264,8 +256,6 @@ void on_login_complete(shared_ptr s, shared_ptr c) { } } - - void on_disconnect(shared_ptr s, shared_ptr c) { // If the client was in a lobby, remove them and notify the other clients if (c->lobby_id) { @@ -279,8 +269,6 @@ void on_disconnect(shared_ptr s, shared_ptr c) { // shortly after this point } - - //////////////////////////////////////////////////////////////////////////////// static void set_console_client_flags( @@ -298,7 +286,7 @@ static void set_console_client_flags( } static void on_DB_V3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (c->channel.crypt_in->type() == PSOEncryption::Type::V2) { @@ -309,7 +297,7 @@ static void on_DB_V3(shared_ptr s, shared_ptr c, uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16); try { auto l = s->license_manager->verify_gc(serial_number, cmd.access_key, - cmd.password); + cmd.password); c->set_license(l); send_command(c, 0x9A, 0x02); @@ -330,7 +318,7 @@ static void on_DB_V3(shared_ptr s, shared_ptr c, return; } else { auto l = LicenseManager::create_license_gc(serial_number, cmd.access_key, - cmd.password, true); + cmd.password, true); s->license_manager->add(l); c->set_license(l); send_command(c, 0x9A, 0x02); @@ -339,7 +327,7 @@ static void on_DB_V3(shared_ptr s, shared_ptr c, } static void on_88_DCNTE(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); c->channel.version = GameVersion::DC; c->flags |= flags_for_version(c->version(), -1); @@ -371,9 +359,9 @@ static void on_88_DCNTE(shared_ptr s, shared_ptr c, } static void on_8B_DCNTE(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, - sizeof(C_Login_DCNTE_8B), sizeof(C_LoginExtended_DCNTE_8B)); + sizeof(C_Login_DCNTE_8B), sizeof(C_LoginExtended_DCNTE_8B)); c->channel.version = GameVersion::DC; c->flags |= flags_for_version(c->version(), -1); c->flags |= Client::Flag::IS_DC_V1 | Client::Flag::IS_TRIAL_EDITION; @@ -416,7 +404,7 @@ static void on_8B_DCNTE(shared_ptr s, shared_ptr c, } static void on_90_DC(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); c->channel.version = GameVersion::DC; c->flags |= flags_for_version(c->version(), -1); @@ -448,15 +436,15 @@ static void on_90_DC(shared_ptr s, shared_ptr c, } static void on_92_DC(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_t(data); send_command(c, 0x92, 0x01); } static void on_93_DC(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, - sizeof(C_LoginV1_DC_93), sizeof(C_LoginExtendedV1_DC_93)); + sizeof(C_LoginV1_DC_93), sizeof(C_LoginExtendedV1_DC_93)); set_console_client_flags(c, cmd.sub_version); uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16); @@ -496,7 +484,7 @@ static void on_93_DC(shared_ptr s, shared_ptr c, } static void on_9A(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); set_console_client_flags(c, cmd.sub_version); @@ -552,7 +540,7 @@ static void on_9A(shared_ptr s, shared_ptr c, } static void on_9C(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); c->flags |= flags_for_version(c->version(), cmd.sub_version); @@ -567,7 +555,7 @@ static void on_9C(shared_ptr s, shared_ptr c, break; case GameVersion::GC: l = s->license_manager->verify_gc(serial_number, cmd.access_key, - cmd.password); + cmd.password); break; case GameVersion::XB: throw runtime_error("xbox licenses are not implemented"); @@ -594,11 +582,11 @@ static void on_9C(shared_ptr s, shared_ptr c, case GameVersion::DC: case GameVersion::PC: l = LicenseManager::create_license_pc(serial_number, cmd.access_key, - true); + true); break; case GameVersion::GC: l = LicenseManager::create_license_gc(serial_number, cmd.access_key, - cmd.password, true); + cmd.password, true); break; case GameVersion::XB: throw runtime_error("xbox licenses are not implemented"); @@ -614,11 +602,11 @@ static void on_9C(shared_ptr s, shared_ptr c, } static void on_9D_9E(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { const C_Login_DC_PC_GC_9D* base_cmd; if (command == 0x9D) { base_cmd = &check_size_t(data, - sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_PC_9D)); + sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_PC_9D)); if (base_cmd->is_extended) { if (c->version() == GameVersion::PC) { const auto& cmd = check_size_t(data); @@ -637,7 +625,7 @@ static void on_9D_9E(shared_ptr s, shared_ptr c, // GC and XB send different amounts of data in this command. This is how // newserv determines if a V3 client is GC or XB. const auto& cmd = check_size_t(data, - sizeof(C_Login_GC_9E), sizeof(C_LoginExtended_XB_9E)); + sizeof(C_Login_GC_9E), sizeof(C_LoginExtended_XB_9E)); switch (data.size()) { case sizeof(C_Login_GC_9E): case sizeof(C_LoginExtended_GC_9E): @@ -738,9 +726,9 @@ static void on_9D_9E(shared_ptr s, shared_ptr c, } static void on_93_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, - sizeof(C_Login_BB_93) - 8, sizeof(C_Login_BB_93)); + sizeof(C_Login_BB_93) - 8, sizeof(C_Login_BB_93)); bool is_old_format; if (data.size() == sizeof(C_Login_BB_93) - 8) { @@ -801,7 +789,7 @@ static void on_93_BB(shared_ptr s, shared_ptr c, case ClientStateBB::INITIAL_LOGIN: // On first login, send the client to the data server port send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at("bb-data1")->port); + s->name_to_port_config.at("bb-data1")->port); break; case ClientStateBB::DOWNLOAD_DATA: @@ -824,7 +812,7 @@ static void on_93_BB(shared_ptr s, shared_ptr c, } static void on_9F_V3(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { if (c->version() == GameVersion::BB) { const auto& cfg = check_size_t(data); c->import_config(cfg); @@ -835,13 +823,13 @@ static void on_9F_V3(shared_ptr, shared_ptr c, } static void on_96(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_t(data); send_server_time(c); } static void on_B1(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_server_time(c); // The B1 command is sent in response to a 97 command, which is normally part @@ -860,10 +848,8 @@ static void on_B1(shared_ptr s, shared_ptr c, } } - - static void on_BA_Ep3(shared_ptr, - shared_ptr c, uint16_t command, uint32_t, const string& data) { + shared_ptr c, uint16_t command, uint32_t, const string& data) { const auto& in_cmd = check_size_t(data); S_Meseta_GC_Ep3_BA out_cmd = {1000000, 1000000, in_cmd.request_token}; @@ -1139,7 +1125,7 @@ static void on_ep3_battle_table_state_updated( } static void on_E4_Ep3(shared_ptr s, - shared_ptr c, uint16_t, uint32_t flag, const string& data) { + shared_ptr c, uint16_t, uint32_t flag, const string& data) { const auto& cmd = check_size_t(data); auto l = s->find_lobby(c->lobby_id); @@ -1181,7 +1167,7 @@ static void on_E4_Ep3(shared_ptr s, } static void on_E5_Ep3(shared_ptr s, - shared_ptr c, uint16_t, uint32_t flag, const string& data) { + shared_ptr c, uint16_t, uint32_t flag, const string& data) { check_size_t(data); auto l = s->find_lobby(c->lobby_id); if (l->is_game() || !l->is_ep3()) { @@ -1201,7 +1187,7 @@ static void on_E5_Ep3(shared_ptr s, } static void on_DC_Ep3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string& data) { + uint16_t, uint32_t flag, const string& data) { check_size_v(data.size(), 0); shared_ptr l; @@ -1265,7 +1251,7 @@ static void on_tournament_bracket_updated( } static void on_CA_Ep3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { shared_ptr l; try { l = s->find_lobby(c->lobby_id); @@ -1318,8 +1304,8 @@ static void on_CA_Ep3(shared_ptr s, shared_ptr c, lobby_data.player_tag = 0x00010000; lobby_data.guild_card = existing_c->license->serial_number; l->battle_record->add_player(lobby_data, - existing_c->game_data.player()->inventory, - existing_c->game_data.player()->disp.to_dcpcv3()); + existing_c->game_data.player()->inventory, + existing_c->game_data.player()->disp.to_dcpcv3()); } } if (l->prev_battle_record) { @@ -1352,7 +1338,7 @@ static void on_CA_Ep3(shared_ptr s, shared_ptr c, } static void on_E2_Ep3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string&) { + uint16_t, uint32_t flag, const string&) { switch (flag) { case 0x00: // Request tournament list send_ep3_tournament_list(s, c, false); @@ -1396,11 +1382,11 @@ static void on_E2_Ep3(shared_ptr s, shared_ptr c, } static void on_D6_V3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); if (c->flags & Client::Flag::IN_INFORMATION_MENU) { send_menu(c, u"Information", MenuID::INFORMATION, - *s->information_menu_for_version(c->version())); + *s->information_menu_for_version(c->version())); } else if (c->flags & Client::Flag::AT_WELCOME_MESSAGE) { send_enable_send_function_call_if_applicable(s, c); c->flags &= ~Client::Flag::AT_WELCOME_MESSAGE; @@ -1410,7 +1396,7 @@ static void on_D6_V3(shared_ptr s, shared_ptr c, } static void on_09(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); switch (cmd.menu_id) { @@ -1530,22 +1516,22 @@ static void on_09(shared_ptr s, shared_ptr c, auto name = encode_sjis(player->disp.name); if (game->is_ep3()) { info += string_printf("%zu: $C6%s$C7 L%" PRIu32 "\n", - x + 1, name.c_str(), player->disp.level + 1); + x + 1, name.c_str(), player->disp.level + 1); } else { info += string_printf("%zu: $C6%s$C7 %s L%" PRIu32 "\n", - x + 1, name.c_str(), - abbreviation_for_char_class(player->disp.char_class), - player->disp.level + 1); + x + 1, name.c_str(), + abbreviation_for_char_class(player->disp.char_class), + player->disp.level + 1); } } } string secid_str = name_for_section_id(game->section_id); info += string_printf("%s %c %s %s\n", - abbreviation_for_episode(game->episode), - abbreviation_for_difficulty(game->difficulty), - abbreviation_for_mode(game->mode), - secid_str.c_str()); + abbreviation_for_episode(game->episode), + abbreviation_for_difficulty(game->difficulty), + abbreviation_for_mode(game->mode), + secid_str.c_str()); bool cheats_enabled = game->flags & Lobby::Flag::CHEATS_ENABLED; bool locked = !game->password.empty(); @@ -1628,17 +1614,17 @@ static void on_09(shared_ptr s, shared_ptr c, message = "(No registrant)"; } else if (team->max_players == 1) { message = string_printf("$C6%s$C7\n%zu %s", - team->name.c_str(), - team->num_rounds_cleared, - team->num_rounds_cleared == 1 ? "win" : "wins"); + team->name.c_str(), + team->num_rounds_cleared, + team->num_rounds_cleared == 1 ? "win" : "wins"); } else { message = string_printf("$C6%s$C7\n%zuH/%zuC\n%zu %s\n%s", - team->name.c_str(), - team->num_human_players(), - team->num_com_players(), - team->num_rounds_cleared, - team->num_rounds_cleared == 1 ? "win" : "wins", - team->password.empty() ? "" : "Locked"); + team->name.c_str(), + team->num_human_players(), + team->num_com_players(), + team->num_rounds_cleared, + team->num_rounds_cleared == 1 ? "win" : "wins", + team->password.empty() ? "" : "Locked"); } send_ship_info(c, decode_sjis(message)); } else { @@ -1657,7 +1643,7 @@ static void on_09(shared_ptr s, shared_ptr c, } static void on_10(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { bool uses_unicode = ((c->version() == GameVersion::PC) || (c->version() == GameVersion::BB)); uint32_t menu_id; @@ -1714,7 +1700,7 @@ static void on_10(shared_ptr s, shared_ptr c, case MainMenuItemID::INFORMATION: send_menu(c, u"Information", MenuID::INFORMATION, - *s->information_menu_for_version(c->version())); + *s->information_menu_for_version(c->version())); c->flags |= Client::Flag::IN_INFORMATION_MENU; break; @@ -1832,7 +1818,7 @@ static void on_10(shared_ptr s, shared_ptr c, c->options.zero_remote_guild_card = !c->options.zero_remote_guild_card; resend_proxy_options_menu: send_menu(c, s->name.c_str(), MenuID::PROXY_OPTIONS, - proxy_options_menu_for_client(s, c)); + proxy_options_menu_for_client(s, c)); break; default: send_message_box(c, u"Incorrect menu item ID."); @@ -1847,13 +1833,14 @@ static void on_10(shared_ptr s, shared_ptr c, } else if (item_id == ProxyDestinationsMenuItemID::OPTIONS) { send_menu(c, s->name.c_str(), MenuID::PROXY_OPTIONS, - proxy_options_menu_for_client(s, c)); + proxy_options_menu_for_client(s, c)); } else { const pair* dest = nullptr; try { dest = &s->proxy_destinations_for_version(c->version()).at(item_id); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } if (!dest) { send_message_box(c, u"$C6No such destination exists."); @@ -1947,8 +1934,8 @@ static void on_10(shared_ptr s, shared_ptr c, } shared_ptr l = c->lobby_id ? s->find_lobby(c->lobby_id) : nullptr; auto quests = s->quest_index->filter(c->version(), - c->flags & Client::Flag::IS_DC_V1, - static_cast(item_id & 0xFF)); + c->flags & Client::Flag::IS_DC_V1, + static_cast(item_id & 0xFF)); // Hack: Assume the menu to be sent is the download quest menu if the // client is not in any lobby @@ -2004,9 +1991,9 @@ static void on_10(shared_ptr s, shared_ptr c, } send_open_quest_file(l->clients[x], bin_basename + ".bin", - bin_basename, bin_contents, QuestFileType::ONLINE); + bin_basename, bin_contents, QuestFileType::ONLINE); send_open_quest_file(l->clients[x], dat_basename + ".dat", - dat_basename, dat_contents, QuestFileType::ONLINE); + dat_basename, dat_contents, QuestFileType::ONLINE); // There is no such thing as command AC on PSO V2 - quests just start // immediately when they're done downloading. (This is also the case @@ -2033,10 +2020,10 @@ static void on_10(shared_ptr s, shared_ptr c, q = q->create_download_quest(); } send_open_quest_file(c, quest_name, bin_basename, q->bin_contents(), - is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD); + is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD); if (dat_contents) { send_open_quest_file(c, quest_name, dat_basename, q->dat_contents(), - is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD); + is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD); } } break; @@ -2086,7 +2073,7 @@ static void on_10(shared_ptr s, shared_ptr c, auto tourn = s->ep3_tournament_index->get_tournament(item_id); if (tourn) { send_ep3_tournament_entry_list(c, tourn, - (menu_id == MenuID::TOURNAMENTS_FOR_SPEC)); + (menu_id == MenuID::TOURNAMENTS_FOR_SPEC)); } break; } @@ -2120,7 +2107,8 @@ static void on_10(shared_ptr s, shared_ptr c, After registration ends, start your matches by\n\ standing at the rightmost 4-player Battle Table\n\ in the lobby along with your partner (if any) and\n\ -opponent(s).", tourn->get_name().c_str()); +opponent(s).", + tourn->get_name().c_str()); send_ep3_timed_message_box(c->channel, 240, message.c_str()); s->ep3_tournament_index->save(); @@ -2145,7 +2133,7 @@ opponent(s).", tourn->get_name().c_str()); } static void on_84(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (cmd.menu_id != MenuID::LOBBY) { @@ -2159,8 +2147,8 @@ static void on_84(shared_ptr s, shared_ptr c, c->preferred_lobby_id = cmd.item_id; s->add_client_to_available_lobby(c); - // If the client already is in a lobby, then they're using the lobby - // teleporter; add them to the lobby they requested or send a failure message. + // If the client already is in a lobby, then they're using the lobby + // teleporter; add them to the lobby they requested or send a failure message. } else { shared_ptr new_lobby; try { @@ -2182,20 +2170,20 @@ static void on_84(shared_ptr s, shared_ptr c, } static void on_08_E6(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { check_size_v(data.size(), 0); send_game_menu(c, s, (command == 0xE6), false); } static void on_1F(shared_ptr s, - shared_ptr c, uint16_t, uint32_t, const string& data) { + shared_ptr c, uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_menu(c, u"Information", MenuID::INFORMATION, - *s->information_menu_for_version(c->version()), true); + *s->information_menu_for_version(c->version()), true); } static void on_A0(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string&) { + uint16_t, uint32_t, const string&) { // The client sends data in this command, but none of it is important. We // intentionally don't call check_size here, but just ignore the data. @@ -2216,17 +2204,17 @@ static void on_A0(shared_ptr s, shared_ptr c, const auto& port_name = version_to_login_port_name.at(static_cast(c->version())); send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); + s->name_to_port_config.at(port_name)->port); } static void on_A1(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { // newserv doesn't have blocks; treat block change the same as ship change on_A0(s, c, command, flag, data); } static void on_8E_DCNTE(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { if (c->flags & Client::Flag::IS_TRIAL_EDITION) { on_A0(s, c, command, flag, data); } else { @@ -2235,7 +2223,7 @@ static void on_8E_DCNTE(shared_ptr s, shared_ptr c, } static void on_8F_DCNTE(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { if (c->flags & Client::Flag::IS_TRIAL_EDITION) { on_A1(s, c, command, flag, data); } else { @@ -2243,10 +2231,8 @@ static void on_8F_DCNTE(shared_ptr s, shared_ptr c, } } - - static void send_dol_file_chunk(shared_ptr s, shared_ptr c, - uint32_t start_addr) { + uint32_t start_addr) { size_t offset = start_addr - c->dol_base_addr; if (offset >= c->loading_dol_file->data.size()) { throw logic_error("DOL file offset beyond end of data"); @@ -2261,12 +2247,12 @@ static void send_dol_file_chunk(shared_ptr s, shared_ptr c, size_t progress_percent = ((offset + bytes_to_send) * 100) / c->loading_dol_file->data.size(); string info = string_printf("Loading $C6%s$C7\n%zu%%%% complete", - c->loading_dol_file->name.c_str(), progress_percent); + c->loading_dol_file->name.c_str(), progress_percent); send_ship_info(c, decode_sjis(info)); } static void on_B3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string& data) { + uint16_t, uint32_t flag, const string& data) { const auto& cmd = check_size_t(data); if (flag == 0) { return; @@ -2293,10 +2279,8 @@ static void on_B3(shared_ptr s, shared_ptr c, } } - - static void on_A2(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string& data) { + uint16_t, uint32_t flag, const string& data) { check_size_v(data.size(), 0); if (!s->quest_index) { @@ -2343,7 +2327,7 @@ static void on_A2(shared_ptr s, shared_ptr c, } static void on_AC_V3_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); // If this client is NOT loading, they should not send an AC. Sending an AC to @@ -2385,7 +2369,7 @@ static void on_AC_V3_BB(shared_ptr s, shared_ptr c, } static void on_AA(shared_ptr s, - shared_ptr c, uint16_t, uint32_t, const string& data) { + shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (c->flags & Client::Flag::IS_TRIAL_EDITION) { @@ -2407,7 +2391,7 @@ static void on_AA(shared_ptr s, } static void on_D7_GC(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { string filename(data); strip_trailing_zeroes(filename); @@ -2441,27 +2425,25 @@ static void send_file_chunk( } static void on_44_A6_V3_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { const auto& cmd = check_size_t(data); send_file_chunk(c, cmd.filename, 0, (command == 0xA6)); } static void on_13_A7_V3_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { const auto& cmd = check_size_t(data); send_file_chunk(c, cmd.filename, flag + 1, (command == 0xA7)); } - - static void on_61_98(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { switch (c->version()) { case GameVersion::DC: case GameVersion::PC: { const auto& pd = check_size_t(data, - sizeof(PSOPlayerDataDCPC), 0xFFFF); + sizeof(PSOPlayerDataDCPC), 0xFFFF); c->game_data.import_player(pd); break; } @@ -2477,14 +2459,14 @@ static void on_61_98(shared_ptr s, shared_ptr c, pd = reinterpret_cast(pd3); } else { pd = &check_size_t(data, sizeof(PSOPlayerDataV3), - sizeof(PSOPlayerDataV3) + c->game_data.player()->auto_reply.bytes()); + sizeof(PSOPlayerDataV3) + c->game_data.player()->auto_reply.bytes()); } c->game_data.import_player(*pd); break; } case GameVersion::BB: { const auto& pd = check_size_t(data, sizeof(PSOPlayerDataBB), - sizeof(PSOPlayerDataBB) + c->game_data.player()->auto_reply.bytes()); + sizeof(PSOPlayerDataBB) + c->game_data.player()->auto_reply.bytes()); c->game_data.import_player(pd); break; } @@ -2496,7 +2478,7 @@ static void on_61_98(shared_ptr s, shared_ptr c, if (player) { string name_str = remove_language_marker(encode_sjis(player->disp.name)); c->channel.name = string_printf("C-%" PRIX64 " (%s)", - c->id, name_str.c_str()); + c->id, name_str.c_str()); } // 98 should only be sent when leaving a game, and we should leave the client @@ -2523,9 +2505,9 @@ static void on_61_98(shared_ptr s, shared_ptr c, if (!failure) { send_text_message_printf(c, - "$C6BB player data saved\nas player %hhu for user\n%s", - static_cast(c->pending_bb_save_player_index + 1), - c->pending_bb_save_username.c_str()); + "$C6BB player data saved\nas player %hhu for user\n%s", + static_cast(c->pending_bb_save_player_index + 1), + c->pending_bb_save_username.c_str()); } c->game_data.bb_username = prev_bb_username; @@ -2542,10 +2524,8 @@ static void on_61_98(shared_ptr s, shared_ptr c, } } - - static void on_6x_C9_CB(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { check_size_v(data.size(), 4, 0xFFFF); auto l = s->find_lobby(c->lobby_id); @@ -2556,10 +2536,8 @@ static void on_6x_C9_CB(shared_ptr s, shared_ptr c, on_subcommand(s, l, c, command, flag, data); } - - static void on_chat_generic(shared_ptr s, shared_ptr c, - const u16string& text) { + const u16string& text) { if (text.empty()) { return; @@ -2600,8 +2578,8 @@ static void on_chat_generic(shared_ptr s, shared_ptr c, continue; } send_chat_message(l->clients[x], c->license->serial_number, - c->game_data.player()->disp.name.data(), processed_text.c_str(), - private_flags); + c->game_data.player()->disp.name.data(), processed_text.c_str(), + private_flags); } if (l->battle_record && l->battle_record->battle_in_progress()) { @@ -2614,7 +2592,7 @@ static void on_chat_generic(shared_ptr s, shared_ptr c, } static void on_06_PC_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, sizeof(C_Chat_06), 0xFFFF); u16string text(cmd.text.pcbb, (data.size() - sizeof(C_Chat_06)) / sizeof(char16_t)); strip_trailing_zeroes(text); @@ -2622,16 +2600,14 @@ static void on_06_PC_BB(shared_ptr s, shared_ptr c, } static void on_06_DC_V3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, sizeof(C_Chat_06), 0xFFFF); u16string decoded_s = decode_sjis(cmd.text.dcv3, data.size() - sizeof(C_Chat_06)); on_chat_generic(s, c, decoded_s); } - - static void on_00E0_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_team_and_key_config_bb(c); c->game_data.account()->newserv_flags &= ~AccountFlag::IN_DRESSING_ROOM; @@ -2639,7 +2615,7 @@ static void on_00E0_BB(shared_ptr, shared_ptr c, } static void on_00E3_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (c->bb_game_state == ClientStateBB::CHOOSE_PLAYER) { @@ -2670,7 +2646,7 @@ static void on_00E3_BB(shared_ptr, shared_ptr c, } static void on_00E8_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { constexpr size_t max_count = sizeof(GuildCardFileBB::entries) / sizeof(GuildCardEntryBB); constexpr size_t max_blocked = sizeof(GuildCardFileBB::blocked) / sizeof(GuildCardBB); switch (command) { @@ -2678,7 +2654,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, const auto& cmd = check_size_t(data); uint32_t checksum = c->game_data.account()->guild_cards.checksum(); c->log.info("(Guild card file) Server checksum = %08" PRIX32 ", client checksum = %08" PRIX32, - checksum, cmd.checksum.load()); + checksum, cmd.checksum.load()); S_GuildCardChecksumResponse_BB_02E8 response = { (cmd.checksum != checksum), 0}; send_command_t(c, 0x02E8, 0x00000000, response); @@ -2696,7 +2672,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, gcf.entries[z].data = new_gc; gcf.entries[z].unknown_a1.clear(0); c->log.info("Added guild card %" PRIu32 " at position %zu", - new_gc.guild_card_number.load(), z); + new_gc.guild_card_number.load(), z); break; } } @@ -2708,7 +2684,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, for (size_t z = 0; z < max_count; z++) { if (gcf.entries[z].data.guild_card_number == cmd.guild_card_number) { c->log.info("Deleted guild card %" PRIu32 " at position %zu", - cmd.guild_card_number.load(), z); + cmd.guild_card_number.load(), z); for (z = 0; z < max_count - 1; z++) { gcf.entries[z] = gcf.entries[z + 1]; } @@ -2725,7 +2701,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, if (gcf.entries[z].data.guild_card_number == new_gc.guild_card_number) { gcf.entries[z].data = new_gc; c->log.info("Updated guild card %" PRIu32 " at position %zu", - new_gc.guild_card_number.load(), z); + new_gc.guild_card_number.load(), z); } } break; @@ -2737,7 +2713,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, if (!gcf.blocked[z].present) { gcf.blocked[z] = new_gc; c->log.info("Added blocked guild card %" PRIu32 " at position %zu", - new_gc.guild_card_number.load(), z); + new_gc.guild_card_number.load(), z); // Note: The client also sends a C6 command, so we don't have to // manually sync the actual blocked senders list here break; @@ -2751,7 +2727,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, for (size_t z = 0; z < max_blocked; z++) { if (gcf.blocked[z].guild_card_number == cmd.guild_card_number) { c->log.info("Deleted blocked guild card %" PRIu32 " at position %zu", - cmd.guild_card_number.load(), z); + cmd.guild_card_number.load(), z); for (z = 0; z < max_blocked - 1; z++) { gcf.blocked[z] = gcf.blocked[z + 1]; } @@ -2770,7 +2746,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, if (gcf.entries[z].data.guild_card_number == cmd.guild_card_number) { gcf.entries[z].comment = cmd.comment; c->log.info("Updated comment on guild card %" PRIu32 " at position %zu", - cmd.guild_card_number.load(), z); + cmd.guild_card_number.load(), z); break; } } @@ -2800,7 +2776,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, } gcf.entries[index] = moved_gc; c->log.info("Moved guild card %" PRIu32 " to position %zu", - cmd.guild_card_number.load(), index); + cmd.guild_card_number.load(), index); break; } default: @@ -2809,7 +2785,7 @@ static void on_00E8_BB(shared_ptr, shared_ptr c, } static void on_DC_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (cmd.cont) { send_guild_card_chunk_bb(c, cmd.chunk_index); @@ -2817,7 +2793,7 @@ static void on_DC_BB(shared_ptr, shared_ptr c, } static void on_xxEB_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { check_size_v(data.size(), 0); if (command == 0x04EB) { @@ -2830,7 +2806,7 @@ static void on_xxEB_BB(shared_ptr, shared_ptr c, } static void on_00EC_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (cmd.reason == 2) { c->game_data.account()->newserv_flags |= AccountFlag::IN_DRESSING_ROOM; @@ -2842,7 +2818,7 @@ static void on_00EC_BB(shared_ptr, shared_ptr c, } static void on_00E5_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (!c->license) { @@ -2892,7 +2868,7 @@ static void on_00E5_BB(shared_ptr s, shared_ptr c, } static void on_xxED_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { const auto* cmd = reinterpret_cast(data.data()); switch (command) { @@ -2930,7 +2906,7 @@ static void on_xxED_BB(shared_ptr, shared_ptr c, } static void on_00E7_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); // We only trust the player's quest data and challenge data. @@ -2940,18 +2916,16 @@ static void on_00E7_BB(shared_ptr, shared_ptr c, } static void on_00E2_BB(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { // Some clients have only a uint32_t at the end for team rewards auto& cmd = check_size_t(data, - sizeof(KeyAndTeamConfigBB) - 4, sizeof(KeyAndTeamConfigBB)); + sizeof(KeyAndTeamConfigBB) - 4, sizeof(KeyAndTeamConfigBB)); c->game_data.account()->key_config = cmd; // TODO: We should probably send a response here, but I don't know which one! } - - static void on_89(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string& data) { + uint16_t, uint32_t flag, const string& data) { check_size_v(data.size(), 0); c->lobby_arrow_color = flag; @@ -2962,23 +2936,24 @@ static void on_89(shared_ptr s, shared_ptr c, } static void on_40(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); try { auto result = s->find_client(nullptr, cmd.target_guild_card_number); auto result_lobby = s->find_lobby(result->lobby_id); send_card_search_result(s, c, result, result_lobby); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } static void on_C0(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string&) { + uint16_t, uint32_t, const string&) { // TODO: Implement choice search. send_text_message(c, u"$C6Choice Search is\nnot supported"); } static void on_81(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { u16string message; uint32_t to_guild_card_number; switch (c->version()) { @@ -3009,7 +2984,8 @@ static void on_81(shared_ptr s, shared_ptr c, shared_ptr target; try { target = s->find_client(nullptr, to_guild_card_number); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } if (!target) { // TODO: We should store pending messages for accounts somewhere, and send @@ -3029,8 +3005,8 @@ static void on_81(shared_ptr s, shared_ptr c, // forward the message in this case. if (!target->game_data.player()->auto_reply.empty()) { send_simple_mail(c, target->license->serial_number, - target->game_data.player()->disp.name, - target->game_data.player()->auto_reply); + target->game_data.player()->disp.name, + target->game_data.player()->auto_reply); } // Forward the message @@ -3042,17 +3018,15 @@ static void on_81(shared_ptr s, shared_ptr c, } } - - static void on_D8(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_info_board(c, s->find_lobby(c->lobby_id)); } template void on_D9_t(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0, c->game_data.player()->info_board.size() * sizeof(CharT)); c->game_data.player()->info_board.assign( reinterpret_cast(data.data()), @@ -3060,17 +3034,17 @@ void on_D9_t(shared_ptr, shared_ptr c, } void on_D9_a(shared_ptr s, shared_ptr c, - uint16_t cmd, uint32_t flag, const string& data) { + uint16_t cmd, uint32_t flag, const string& data) { on_D9_t(s, c, cmd, flag, data); } void on_D9_w(shared_ptr s, shared_ptr c, - uint16_t cmd, uint32_t flag, const string& data) { + uint16_t cmd, uint32_t flag, const string& data) { on_D9_t(s, c, cmd, flag, data); } template void on_C7_t(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0, c->game_data.player()->auto_reply.size() * sizeof(CharT)); c->game_data.player()->auto_reply.assign( reinterpret_cast(data.data()), @@ -3078,22 +3052,22 @@ void on_C7_t(shared_ptr, shared_ptr c, } void on_C7_a(shared_ptr s, shared_ptr c, - uint16_t cmd, uint32_t flag, const string& data) { + uint16_t cmd, uint32_t flag, const string& data) { on_C7_t(s, c, cmd, flag, data); } void on_C7_w(shared_ptr s, shared_ptr c, - uint16_t cmd, uint32_t flag, const string& data) { + uint16_t cmd, uint32_t flag, const string& data) { on_C7_t(s, c, cmd, flag, data); } static void on_C8(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); c->game_data.player()->auto_reply.clear(0); } static void on_C6(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { if (c->version() == GameVersion::BB) { const auto& cmd = check_size_t(data); c->game_data.account()->blocked_senders = cmd.blocked_senders; @@ -3103,8 +3077,6 @@ static void on_C6(shared_ptr, shared_ptr c, } } - - shared_ptr create_game_generic( shared_ptr s, shared_ptr c, @@ -3178,12 +3150,13 @@ shared_ptr create_game_generic( shared_ptr game = s->create_lobby(); game->name = name; game->flags = flags | - Lobby::Flag::GAME | - (item_tracking_enabled ? Lobby::Flag::ITEM_TRACKING_ENABLED : 0); + Lobby::Flag::GAME | + (item_tracking_enabled ? Lobby::Flag::ITEM_TRACKING_ENABLED : 0); game->password = password; game->version = c->version(); game->section_id = c->options.override_section_id >= 0 - ? c->options.override_section_id : c->game_data.player()->disp.section_id; + ? c->options.override_section_id + : c->game_data.player()->disp.section_id; game->episode = episode; game->mode = mode; game->difficulty = difficulty; @@ -3237,7 +3210,7 @@ shared_ptr create_game_generic( for (size_t area = 0; area < 0x10; area++) { c->log.info("[Map/%zu] Using variations %" PRIX32 ", %" PRIX32, - area, game->variations[area * 2].load(), game->variations[area * 2 + 1].load()); + area, game->variations[area * 2].load(), game->variations[area * 2 + 1].load()); auto filenames = map_filenames_for_variation( game->episode, is_solo, @@ -3265,7 +3238,7 @@ shared_ptr create_game_generic( area_enemies.begin(), area_enemies.end()); c->log.info("[Map/%zu] Loaded %s (%zu entries)", - area, filename.c_str(), area_enemies.size()); + area, filename.c_str(), area_enemies.size()); for (size_t z = 0; z < area_enemies.size(); z++) { string e_str = area_enemies[z].str(); static_game_data_log.info("(Entry %zX) %s", z, e_str.c_str()); @@ -3287,7 +3260,7 @@ shared_ptr create_game_generic( } static void on_C1_PC(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); uint32_t flags = Lobby::Flag::NON_V1_ONLY; @@ -3306,7 +3279,7 @@ static void on_C1_PC(shared_ptr s, shared_ptr c, } static void on_0C_C1_E7_EC(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t, const string& data) { + uint16_t command, uint32_t, const string& data) { const auto& cmd = check_size_t(data); // Only allow E7/EC from Ep3 clients @@ -3368,7 +3341,7 @@ static void on_0C_C1_E7_EC(shared_ptr s, shared_ptr c, } static void on_C1_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); uint32_t flags = Lobby::Flag::NON_V1_ONLY; @@ -3407,7 +3380,7 @@ static void on_C1_BB(shared_ptr s, shared_ptr c, } static void on_8A(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { if ((c->version() == GameVersion::DC) && (c->flags & Client::Flag::IS_TRIAL_EDITION)) { const auto& cmd = check_size_t(data); set_console_client_flags(c, cmd.sub_version); @@ -3424,7 +3397,7 @@ static void on_8A(shared_ptr s, shared_ptr c, } static void on_6F(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); auto l = s->find_lobby(c->lobby_id); @@ -3450,16 +3423,13 @@ static void on_6F(shared_ptr s, shared_ptr c, watched_lobby->ep3_server_base->server->send_commands_for_joining_spectator(c->channel); } - // If there are more players to bring in, try to do so c->disconnect_hooks.erase(ADD_NEXT_CLIENT_DISCONNECT_HOOK_NAME); add_next_game_client(s, l); } - - static void on_D0_V3_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { auto& cmd = check_size_t(data); if (c->game_data.pending_item_trade) { @@ -3499,7 +3469,7 @@ static void on_D0_V3_BB(shared_ptr s, shared_ptr c, } static void on_D2_V3_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); if (!c->game_data.pending_item_trade) { @@ -3530,7 +3500,7 @@ static void on_D2_V3_BB(shared_ptr s, shared_ptr c, } static void on_D4_V3_BB(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); // Annoyingly, if the other client disconnects at a certain point during the @@ -3560,10 +3530,8 @@ static void on_D4_V3_BB(shared_ptr s, shared_ptr c, send_command(target_c, 0xD4, 0x00); } - - static void on_EE_Ep3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t flag, const string& data) { + uint16_t, uint32_t flag, const string& data) { if (!(c->flags & Client::Flag::IS_EPISODE_3)) { throw runtime_error("non-Ep3 client sent card trade command"); } @@ -3666,7 +3634,7 @@ static void on_EE_Ep3(shared_ptr s, shared_ptr c, } static void on_EF_Ep3(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); if (!(c->flags & Client::Flag::IS_EPISODE_3)) { @@ -3687,10 +3655,8 @@ static void on_EF_Ep3(shared_ptr s, shared_ptr c, send_card_auction_if_all_clients_ready(s, l); } - - static void on_xxEA_BB(shared_ptr, shared_ptr c, - uint16_t command, uint32_t, const string&) { + uint16_t command, uint32_t, const string&) { // TODO: Implement teams. This command has a very large number of subcommands // (up to 20EA!). @@ -3703,10 +3669,8 @@ static void on_xxEA_BB(shared_ptr, shared_ptr c, } } - - static void on_02_P(shared_ptr, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_command(c, 0x04, 0x00); // This requests the user's login information } @@ -3743,7 +3707,7 @@ static void change_to_directory_patch( } static void on_04_P(shared_ptr s, shared_ptr c, - uint16_t, uint32_t, const string& data) { + uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); try { @@ -3773,13 +3737,13 @@ static void on_04_P(shared_ptr s, shared_ptr c, // On BB we can use colors and newlines should be \n; on PC we can't use // colors, the text is auto-word-wrapped, and newlines should be \r\n. const u16string& message = (c->flags & Client::Flag::IS_BB_PATCH) - ? s->bb_patch_server_message : s->pc_patch_server_message; + ? s->bb_patch_server_message + : s->pc_patch_server_message; if (!message.empty()) { send_message_box(c, message.c_str()); } - auto index = (c->flags & Client::Flag::IS_BB_PATCH) ? - s->bb_patch_file_index : s->pc_patch_file_index; + auto index = (c->flags & Client::Flag::IS_BB_PATCH) ? s->bb_patch_file_index : s->pc_patch_file_index; if (index.get()) { send_command(c, 0x0B, 0x00); // Start patch session; go to root directory @@ -3810,7 +3774,7 @@ static void on_04_P(shared_ptr s, shared_ptr c, } static void on_0F_P(shared_ptr, - shared_ptr c, uint16_t, uint32_t, const string& data) { + shared_ptr c, uint16_t, uint32_t, const string& data) { auto& cmd = check_size_t(data); auto& req = c->patch_file_checksum_requests.at(cmd.request_id); req.crc32 = cmd.checksum; @@ -3819,7 +3783,7 @@ static void on_0F_P(shared_ptr, } static void on_10_P(shared_ptr, - shared_ptr c, uint16_t, uint32_t, const string&) { + shared_ptr c, uint16_t, uint32_t, const string&) { S_StartFileDownloads_Patch_11 start_cmd = {0, 0}; for (const auto& req : c->patch_file_checksum_requests) { @@ -3828,7 +3792,7 @@ static void on_10_P(shared_ptr, } if (req.needs_update()) { c->log.info("File %s needs update (CRC: %08" PRIX32 "/%08" PRIX32 ", size: %" PRIu32 "/%" PRIu32 ")", - req.file->name.c_str(), req.file->crc32, req.crc32, req.file->size, req.size); + req.file->name.c_str(), req.file->crc32, req.crc32, req.file->size, req.size); start_cmd.total_bytes += req.file->size; start_cmd.num_files++; } else { @@ -3851,27 +3815,24 @@ static void on_10_P(shared_ptr, send_command(c, 0x12, 0x00); } - - static void on_ignored(shared_ptr, shared_ptr, - uint16_t, uint32_t, const string&) { } + uint16_t, uint32_t, const string&) {} static void on_unimplemented_command(shared_ptr, - shared_ptr c, uint16_t command, uint32_t flag, const string& data) { + shared_ptr c, uint16_t command, uint32_t flag, const string& data) { c->log.warning("Unknown command: size=%04zX command=%04hX flag=%08" PRIX32, - data.size(), command, flag); + data.size(), command, flag); throw invalid_argument("unimplemented command"); } - - typedef void (*on_command_t)(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data); + uint16_t command, uint32_t flag, const string& data); // Command handler table, indexed by command number and game version. Null // entries in this table cause on_unimplemented_command to be called, which // disconnects the client. static on_command_t handlers[0x100][6] = { + // clang-format off // PATCH DC PC GC XB BB /* 00 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 01 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, @@ -4137,6 +4098,7 @@ static on_command_t handlers[0x100][6] = { /* FE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* FF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, // PATCH DC PC GC XB BB + // clang-format on }; static void check_unlicensed_command(GameVersion version, uint8_t command) { @@ -4181,7 +4143,7 @@ static void check_unlicensed_command(GameVersion version, uint8_t command) { } void on_command(shared_ptr s, shared_ptr c, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const string& data) { string encoded_name; auto player = c->game_data.player(false); if (player) { @@ -4205,26 +4167,26 @@ void on_command(shared_ptr s, shared_ptr c, } void on_command_with_header(shared_ptr s, shared_ptr c, - string& data) { + string& data) { switch (c->version()) { case GameVersion::DC: case GameVersion::GC: case GameVersion::XB: { auto& header = check_size_t(data, - sizeof(PSOCommandHeaderDCV3), 0xFFFF); + sizeof(PSOCommandHeaderDCV3), 0xFFFF); on_command(s, c, header.command, header.flag, data.substr(sizeof(header))); break; } case GameVersion::PC: case GameVersion::PATCH: { auto& header = check_size_t(data, - sizeof(PSOCommandHeaderPC), 0xFFFF); + sizeof(PSOCommandHeaderPC), 0xFFFF); on_command(s, c, header.command, header.flag, data.substr(sizeof(header))); break; } case GameVersion::BB: { auto& header = check_size_t(data, - sizeof(PSOCommandHeaderBB), 0xFFFF); + sizeof(PSOCommandHeaderBB), 0xFFFF); on_command(s, c, header.command, header.flag, data.substr(sizeof(header))); break; } diff --git a/src/ReceiveCommands.hh b/src/ReceiveCommands.hh index ee0dc5db..d1ad0472 100644 --- a/src/ReceiveCommands.hh +++ b/src/ReceiveCommands.hh @@ -4,8 +4,6 @@ #include "Client.hh" #include "ServerState.hh" - - std::shared_ptr create_game_generic( std::shared_ptr s, std::shared_ptr c, diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index b0adf6b9..b0a1113f 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -3,16 +3,16 @@ #include #include -#include #include +#include #include "Client.hh" #include "Items.hh" #include "Lobby.hh" #include "Loggers.hh" #include "Map.hh" -#include "Player.hh" #include "PSOProtocol.hh" +#include "Player.hh" #include "SendCommands.hh" #include "StaticGameData.hh" #include "Text.hh" @@ -22,14 +22,10 @@ using namespace std; // The functions in this file are called when a client sends a game command // (60, 62, 6C, 6D, C9, or CB). - - bool command_is_private(uint8_t command) { return (command == 0x62) || (command == 0x6D); } - - template const CmdT& check_size_sc( const string& data, @@ -62,16 +58,14 @@ const CmdT& check_size_sc( return cmd; } - - static const unordered_set watcher_subcommands({ - 0x07, // Symbol chat - 0x74, // Word select - 0xBD, // Word select during battle (with private_flags) + 0x07, // Symbol chat + 0x74, // Word select + 0xBD, // Word select during battle (with private_flags) }); static void forward_subcommand(shared_ptr l, shared_ptr c, - uint8_t command, uint8_t flag, const void* data, size_t size) { + uint8_t command, uint8_t flag, const void* data, size_t size) { // if the command is an Ep3-only command, make sure an Ep3 client sent it bool command_is_ep3 = (command & 0xF0) == 0xC0; @@ -109,8 +103,8 @@ static void forward_subcommand(shared_ptr l, shared_ptr c, // battle, forward everything to watcher lobbies. if (size && (watcher_subcommands.count(*reinterpret_cast(data) || - (l->ep3_server_base && - l->ep3_server_base->server->setup_phase != Episode3::SetupPhase::REGISTRATION)))) { + (l->ep3_server_base && + l->ep3_server_base->server->setup_phase != Episode3::SetupPhase::REGISTRATION)))) { for (const auto& watcher_lobby : l->watcher_lobbies) { forward_subcommand(watcher_lobby, c, command, flag, data, size); } @@ -118,41 +112,39 @@ static void forward_subcommand(shared_ptr l, shared_ptr c, if (l->battle_record && l->battle_record->battle_in_progress()) { auto type = ((command & 0xF0) == 0xC0) - ? Episode3::BattleRecord::Event::Type::EP3_GAME_COMMAND - : Episode3::BattleRecord::Event::Type::GAME_COMMAND; + ? Episode3::BattleRecord::Event::Type::EP3_GAME_COMMAND + : Episode3::BattleRecord::Event::Type::GAME_COMMAND; l->battle_record->add_command(type, data, size); } } } static void forward_subcommand(shared_ptr l, shared_ptr c, - uint8_t command, uint8_t flag, const string& data) { + uint8_t command, uint8_t flag, const string& data) { forward_subcommand(l, c, command, flag, data.data(), data.size()); } - - static void on_invalid(shared_ptr, - shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc( data, sizeof(G_UnusedHeader), 0xFFFF); if (command_is_private(command)) { c->log.error("Invalid subcommand: %02hhX (private to %hhu)", - cmd.subcommand, flag); + cmd.subcommand, flag); } else { c->log.error("Invalid subcommand: %02hhX (public)", cmd.subcommand); } } static void on_unimplemented(shared_ptr, - shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc( data, sizeof(G_UnusedHeader), 0xFFFF); if (command_is_private(command)) { c->log.warning("Unknown subcommand: %02hhX (private to %hhu)", - cmd.subcommand, flag); + cmd.subcommand, flag); } else { c->log.warning("Unknown subcommand: %02hhX (public)", cmd.subcommand); } @@ -161,18 +153,16 @@ static void on_unimplemented(shared_ptr, } } - - static void on_forward_check_size(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { check_size_sc(data, sizeof(G_UnusedHeader), 0xFFFF); forward_subcommand(l, c, command, flag, data); } static void on_forward_check_game(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (!l->is_game()) { return; } @@ -180,8 +170,8 @@ static void on_forward_check_game(shared_ptr, } static void on_forward_check_game_loading(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (!l->is_game() || !l->any_client_loading()) { return; } @@ -189,8 +179,8 @@ static void on_forward_check_game_loading(shared_ptr, } static void on_forward_check_size_client(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc( data, sizeof(G_ClientIDHeader), 0xFFFF); if (cmd.client_id != c->lobby_client_id) { @@ -200,8 +190,8 @@ static void on_forward_check_size_client(shared_ptr, } static void on_forward_check_size_game(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { check_size_sc(data, sizeof(G_UnusedHeader), 0xFFFF); if (!l->is_game()) { return; @@ -210,8 +200,8 @@ static void on_forward_check_size_game(shared_ptr, } static void on_forward_check_size_ep3_lobby(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { check_size_sc(data, sizeof(G_UnusedHeader), 0xFFFF); if (l->is_game() || !l->is_ep3()) { return; @@ -220,8 +210,8 @@ static void on_forward_check_size_ep3_lobby(shared_ptr, } static void on_forward_check_size_ep3_game(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { check_size_sc(data, sizeof(G_UnusedHeader), 0xFFFF); if (!l->is_game() || !l->is_ep3()) { return; @@ -229,14 +219,12 @@ static void on_forward_check_size_ep3_game(shared_ptr, forward_subcommand(l, c, command, flag, data); } - - //////////////////////////////////////////////////////////////////////////////// // Ep3 subcommands static void on_ep3_battle_subs(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& orig_data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& orig_data) { const auto& header = check_size_sc( orig_data, sizeof(G_CardBattleCommandHeader), 0xFFFF); if (!l->is_game() || !l->is_ep3()) { @@ -268,14 +256,12 @@ static void on_ep3_battle_subs(shared_ptr s, forward_subcommand(l, c, command, flag, data); } - - //////////////////////////////////////////////////////////////////////////////// // Chat commands and the like static void on_send_guild_card(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (!command_is_private(command) || !l || (flag >= l->max_clients) || (!l->clients[flag])) { return; @@ -311,8 +297,8 @@ static void on_send_guild_card(shared_ptr, // client sends a symbol chat static void on_symbol_chat(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!c->can_chat || (cmd.client_id != c->lobby_client_id)) { @@ -323,8 +309,8 @@ static void on_symbol_chat(shared_ptr, // client sends a word select chat static void on_word_select(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!c->can_chat || (cmd.header.client_id != c->lobby_client_id)) { @@ -336,8 +322,8 @@ static void on_word_select(shared_ptr, // client is done loading into a lobby (we use this to trigger arrow updates) static void on_set_player_visibility(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (cmd.header.client_id != c->lobby_client_id) { @@ -355,8 +341,8 @@ static void on_set_player_visibility(shared_ptr, // Game commands used by cheat mechanisms static void on_change_area(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!l->is_game()) { return; @@ -367,8 +353,8 @@ static void on_change_area(shared_ptr, // when a player is hit by an enemy, heal them if infinite HP is enabled static void on_hit_by_enemy(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, sizeof(G_ClientIDHeader), 0xFFFF); if (!l->is_game() || (cmd.client_id != c->lobby_client_id)) { return; @@ -381,8 +367,8 @@ static void on_hit_by_enemy(shared_ptr, // when a player casts a tech, restore TP if infinite TP is enabled static void on_cast_technique_finished(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!l->is_game() || (cmd.header.client_id != c->lobby_client_id)) { return; @@ -394,10 +380,10 @@ static void on_cast_technique_finished(shared_ptr, } static void on_attack_finished(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - offsetof(G_AttackFinished_6x46, entries), sizeof(G_AttackFinished_6x46)); + offsetof(G_AttackFinished_6x46, entries), sizeof(G_AttackFinished_6x46)); size_t allowed_count = min(cmd.header.size - 2, 11); if (cmd.count > allowed_count) { throw runtime_error("invalid attack finished command"); @@ -406,10 +392,10 @@ static void on_attack_finished(shared_ptr s, } static void on_cast_technique(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - offsetof(G_CastTechnique_6x47, targets), sizeof(G_CastTechnique_6x47)); + offsetof(G_CastTechnique_6x47, targets), sizeof(G_CastTechnique_6x47)); size_t allowed_count = min(cmd.header.size - 2, 10); if (cmd.target_count > allowed_count) { throw runtime_error("invalid cast technique command"); @@ -418,10 +404,10 @@ static void on_cast_technique(shared_ptr s, } static void on_subtract_pb_energy(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - offsetof(G_SubtractPBEnergy_6x49, entries), sizeof(G_SubtractPBEnergy_6x49)); + offsetof(G_SubtractPBEnergy_6x49, entries), sizeof(G_SubtractPBEnergy_6x49)); size_t allowed_count = min(cmd.header.size - 3, 14); if (cmd.entry_count > allowed_count) { throw runtime_error("invalid subtract PB energy command"); @@ -430,8 +416,8 @@ static void on_subtract_pb_energy(shared_ptr s, } static void on_switch_state_changed(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { auto& cmd = check_size_t(data); if (!l->is_game()) { return; @@ -445,7 +431,7 @@ static void on_switch_state_changed(shared_ptr, send_text_message(c, u"$C5Switch assist"); } forward_subcommand(l, c, command, flag, &c->last_switch_enabled_command, - sizeof(c->last_switch_enabled_command)); + sizeof(c->last_switch_enabled_command)); send_command_t(c, command, flag, c->last_switch_enabled_command); } c->last_switch_enabled_command = cmd; @@ -456,8 +442,8 @@ static void on_switch_state_changed(shared_ptr, template void on_movement(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (cmd.header.client_id != c->lobby_client_id) { @@ -474,8 +460,8 @@ void on_movement(shared_ptr, // Item commands static void on_player_drop_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if ((cmd.header.client_id != c->lobby_client_id)) { @@ -488,12 +474,12 @@ static void on_player_drop_item(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu dropped item %08" PRIX32 " (%s) at %hu:(%g, %g)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(), - cmd.area.load(), cmd.x.load(), cmd.z.load()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(), + cmd.area.load(), cmd.x.load(), cmd.z.load()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: drop %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); } @@ -502,10 +488,10 @@ static void on_player_drop_item(shared_ptr, } static void on_create_inventory_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - sizeof(G_CreateInventoryItem_DC_6x2B), sizeof(G_CreateInventoryItem_PC_V3_BB_6x2B)); + sizeof(G_CreateInventoryItem_DC_6x2B), sizeof(G_CreateInventoryItem_PC_V3_BB_6x2B)); if ((cmd.header.client_id != c->lobby_client_id)) { return; @@ -525,11 +511,11 @@ static void on_create_inventory_item(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu created inventory item %08" PRIX32 " (%s)", - cmd.header.client_id.load(), cmd.item.id.load(), name.c_str()); + cmd.header.client_id.load(), cmd.item.id.load(), name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: create %08" PRIX32 "\n%s", - cmd.item.id.load(), name.c_str()); + cmd.item.id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); } @@ -538,10 +524,10 @@ static void on_create_inventory_item(shared_ptr, } static void on_drop_partial_stack(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - sizeof(G_DropStackedItem_DC_6x5D), sizeof(G_DropStackedItem_PC_V3_BB_6x5D)); + sizeof(G_DropStackedItem_DC_6x5D), sizeof(G_DropStackedItem_PC_V3_BB_6x5D)); // TODO: Should we check the client ID here too? if (!l->is_game()) { @@ -562,12 +548,12 @@ static void on_drop_partial_stack(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu split stack to create ground item %08" PRIX32 " (%s) at %hu:(%g, %g)", - cmd.header.client_id.load(), item.data.id.load(), name.c_str(), - cmd.area.load(), cmd.x.load(), cmd.z.load()); + cmd.header.client_id.load(), item.data.id.load(), name.c_str(), + cmd.area.load(), cmd.x.load(), cmd.z.load()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: split %08" PRIX32 "\n%s", - item.data.id.load(), name.c_str()); + item.data.id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); } @@ -576,8 +562,8 @@ static void on_drop_partial_stack(shared_ptr, } static void on_drop_partial_stack_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -607,12 +593,12 @@ static void on_drop_partial_stack_bb(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu split stack %08" PRIX32 " (removed: %s) at %hu:(%g, %g)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(), - cmd.area.load(), cmd.x.load(), cmd.z.load()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(), + cmd.area.load(), cmd.x.load(), cmd.z.load()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: split/BB %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); @@ -624,8 +610,8 @@ static void on_drop_partial_stack_bb(shared_ptr, } static void on_buy_shop_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!l->is_game() || (cmd.header.client_id != c->lobby_client_id)) { @@ -644,11 +630,11 @@ static void on_buy_shop_item(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu bought item %08" PRIX32 " (%s) from shop", - cmd.header.client_id.load(), item.data.id.load(), name.c_str()); + cmd.header.client_id.load(), item.data.id.load(), name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: buy %08" PRIX32 "\n%s", - item.data.id.load(), name.c_str()); + item.data.id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); } @@ -657,10 +643,10 @@ static void on_buy_shop_item(shared_ptr, } static void on_box_or_enemy_item_drop(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data, - sizeof(G_DropItem_DC_6x5F), sizeof(G_DropItem_PC_V3_BB_6x5F)); + sizeof(G_DropItem_DC_6x5F), sizeof(G_DropItem_PC_V3_BB_6x5F)); if (!l->is_game() || (c->lobby_client_id != l->leader_id)) { return; @@ -678,21 +664,20 @@ static void on_box_or_enemy_item_drop(shared_ptr, auto name = item.data.name(false); l->log.info("Leader created ground item %08" PRIX32 " (%s) at %hhu:(%g, %g)", - item.data.id.load(), name.c_str(), cmd.area, cmd.x.load(), cmd.z.load()); + item.data.id.load(), name.c_str(), cmd.area, cmd.x.load(), cmd.z.load()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: drop %08" PRIX32 "\n%s", - item.data.id.load(), name.c_str()); + item.data.id.load(), name.c_str()); } } forward_subcommand(l, c, command, flag, data); } - static void on_pick_up_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { auto& cmd = check_size_sc(data); if (!l->is_game()) { @@ -714,11 +699,11 @@ static void on_pick_up_item(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu picked up %08" PRIX32 " (%s)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: pick %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } effective_c->game_data.player()->print_inventory(stderr); } @@ -727,8 +712,8 @@ static void on_pick_up_item(shared_ptr, } static void on_pick_up_item_request(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { // This is handled by the server on BB, and by the leader on other versions if (l->version == GameVersion::BB) { auto& cmd = check_size_sc(data); @@ -746,11 +731,11 @@ static void on_pick_up_item_request(shared_ptr, auto name = item.data.name(false); l->log.info("Player %hu picked up %08" PRIX32 " (%s)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: pick/BB %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); @@ -762,8 +747,8 @@ static void on_pick_up_item_request(shared_ptr, } static void on_equip_unequip_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (cmd.header.client_id != c->lobby_client_id) { @@ -787,8 +772,8 @@ static void on_equip_unequip_item(shared_ptr, } static void on_use_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (cmd.header.client_id != c->lobby_client_id) { @@ -808,10 +793,10 @@ static void on_use_item(shared_ptr, player_use_item(c, index); l->log.info("Player used item %hu:%08" PRIX32 " (%s)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); if (c->options.debug) { send_text_message_printf(c, "$C5Items: use %08" PRIX32 "\n%s", - cmd.item_id.load(), colored_name.c_str()); + cmd.item_id.load(), colored_name.c_str()); } c->game_data.player()->print_inventory(stderr); } @@ -820,8 +805,8 @@ static void on_use_item(shared_ptr, } static void on_open_shop_bb_or_ep3_battle_subs(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (l->is_ep3()) { on_ep3_battle_subs(s, l, c, command, flag, data); @@ -860,7 +845,7 @@ static void on_open_shop_bb_or_ep3_battle_subs(shared_ptr s, } static void on_open_bank_bb_or_card_trade_counter_ep3(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if ((l->version == GameVersion::BB) && l->is_game()) { send_bank(c); } else if ((l->version == GameVersion::GC) && l->is_ep3()) { @@ -869,7 +854,7 @@ static void on_open_bank_bb_or_card_trade_counter_ep3(shared_ptr, } static void on_bank_action_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { + shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -919,8 +904,8 @@ static void on_bank_action_bb(shared_ptr, } static void on_sort_inventory_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t, uint8_t, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t, uint8_t, + const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -973,8 +958,8 @@ static bool drop_item( item.data = l->item_creator->on_box_item_drop(area); } - // If the game is not BB, forward the request to the leader instead of - // generating the item drop command + // If the game is not BB, forward the request to the leader instead of + // generating the item drop command } else { return false; } @@ -989,23 +974,23 @@ static bool drop_item( } static void on_enemy_drop_item_request(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (!l->is_game()) { return; } const auto& cmd = check_size_sc(data, - sizeof(G_EnemyDropItemRequest_DC_6x60), - sizeof(G_EnemyDropItemRequest_PC_V3_BB_6x60)); + sizeof(G_EnemyDropItemRequest_DC_6x60), + sizeof(G_EnemyDropItemRequest_PC_V3_BB_6x60)); if (!drop_item(l, cmd.enemy_id, cmd.area, cmd.x, cmd.z, cmd.enemy_id)) { forward_subcommand(l, c, command, flag, data); } } static void on_box_drop_item_request(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (!l->is_game()) { return; } @@ -1017,8 +1002,8 @@ static void on_box_drop_item_request(shared_ptr, } static void on_phase_setup(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (c->version() == GameVersion::DC || c->version() == GameVersion::PC) { forward_subcommand(l, c, command, flag, data); return; @@ -1050,17 +1035,17 @@ static void on_phase_setup(shared_ptr, auto c = l->clients.at(l->leader_id); if (c) { G_EnemyDropItemRequest_PC_V3_BB_6x60 req = { - { - {0x60, 0x06, 0x0000}, - static_cast(c->area), - static_cast(is_ep2 ? 0x4E : 0x2F), - 0x0B4F, - is_ep2 ? -9999.0f : 10160.58984375f, - 0.0f, - 2, - 0, - }, - 0xE0AEDC01, + { + {0x60, 0x06, 0x0000}, + static_cast(c->area), + static_cast(is_ep2 ? 0x4E : 0x2F), + 0x0B4F, + is_ep2 ? -9999.0f : 10160.58984375f, + 0.0f, + 2, + 0, + }, + 0xE0AEDC01, }; send_command_t(c, 0x62, l->leader_id, req); } @@ -1069,8 +1054,8 @@ static void on_phase_setup(shared_ptr, // enemy hit by player static void on_enemy_hit(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -1092,8 +1077,8 @@ static void on_enemy_hit(shared_ptr, } static void on_enemy_killed(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { forward_subcommand(l, c, command, flag, data); if (l->version == GameVersion::BB) { @@ -1151,7 +1136,7 @@ static void on_enemy_killed(shared_ptr s, send_give_experience(l, other_c, exp); if (other_c->options.debug) { send_text_message_printf(other_c, "$C5+%" PRIu32 " E-%hX (%s)", - exp, cmd.enemy_id.load(), e.type_name); + exp, cmd.enemy_id.load(), e.type_name); } bool leveled_up = false; @@ -1174,8 +1159,8 @@ static void on_enemy_killed(shared_ptr s, } static void on_destroy_inventory_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!l->is_game()) { return; @@ -1188,11 +1173,11 @@ static void on_destroy_inventory_item(shared_ptr, cmd.item_id, cmd.amount, c->version() != GameVersion::BB); auto name = item.data.name(false); l->log.info("Inventory item %hu:%08" PRIX32 " destroyed (%s)", - cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); + cmd.header.client_id.load(), cmd.item_id.load(), name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: destroy %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } c->game_data.player()->print_inventory(stderr); forward_subcommand(l, c, command, flag, data); @@ -1200,8 +1185,8 @@ static void on_destroy_inventory_item(shared_ptr, } static void on_destroy_ground_item(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { const auto& cmd = check_size_sc(data); if (!l->is_game()) { return; @@ -1210,19 +1195,19 @@ static void on_destroy_ground_item(shared_ptr, auto item = l->remove_item(cmd.item_id); auto name = item.data.name(false); l->log.info("Ground item %08" PRIX32 " destroyed (%s)", cmd.item_id.load(), - name.c_str()); + name.c_str()); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: destroy/ground %08" PRIX32 "\n%s", - cmd.item_id.load(), name.c_str()); + cmd.item_id.load(), name.c_str()); } forward_subcommand(l, c, command, flag, data); } } static void on_identify_item_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); if (!l->is_game()) { @@ -1255,8 +1240,8 @@ static void on_identify_item_bb(shared_ptr, } static void on_accept_identify_item_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -1281,7 +1266,7 @@ static void on_accept_identify_item_bb(shared_ptr, } static void on_sell_item_at_shop_bb(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); @@ -1298,12 +1283,12 @@ static void on_sell_item_at_shop_bb(shared_ptr s, auto name = item.data.name(false); l->log.info("Inventory item %hu:%08" PRIX32 " destroyed via sale (%s)", - c->lobby_client_id, cmd.item_id.load(), name.c_str()); + c->lobby_client_id, cmd.item_id.load(), name.c_str()); c->game_data.player()->print_inventory(stderr); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: destroy/sale %08" PRIX32 "\n+%zu Meseta\n%s", - cmd.item_id.load(), price, name.c_str()); + cmd.item_id.load(), price, name.c_str()); } forward_subcommand(l, c, command, flag, data); @@ -1311,7 +1296,7 @@ static void on_sell_item_at_shop_bb(shared_ptr s, } static void on_buy_shop_item_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { + shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { if (l->version == GameVersion::BB) { const auto& cmd = check_size_sc(data); if (!(l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED)) { @@ -1339,18 +1324,18 @@ static void on_buy_shop_item_bb(shared_ptr, auto name = item.data.name(false); l->log.info("Inventory item %hu:%08" PRIX32 " created via purchase (%s) for %zu meseta", - c->lobby_client_id, cmd.inventory_item_id.load(), name.c_str(), price); + c->lobby_client_id, cmd.inventory_item_id.load(), name.c_str(), price); c->game_data.player()->print_inventory(stderr); if (c->options.debug) { string name = item.data.name(true); send_text_message_printf(c, "$C5Items: create/purchase %08" PRIX32 "\n-%zu Meseta\n%s", - cmd.inventory_item_id.load(), price, name.c_str()); + cmd.inventory_item_id.load(), price, name.c_str()); } } } static void on_medical_center_bb(shared_ptr, - shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string&) { + shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string&) { if (l->version == GameVersion::BB) { if (c->game_data.player()->disp.meseta < 10) { @@ -1366,270 +1351,270 @@ static void on_medical_center_bb(shared_ptr, // the handler function, and flags that tell when to allow the command. See command-input-subs.h // for more information on flags. The maximum size is not enforced if it's zero. typedef void (*subcommand_handler_t)(shared_ptr s, - shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, - const string& data); + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data); subcommand_handler_t subcommand_handlers[0x100] = { - /* 00 */ on_invalid, - /* 01 */ nullptr, - /* 02 */ nullptr, - /* 03 */ nullptr, - /* 04 */ nullptr, - /* 05 */ on_switch_state_changed, - /* 06 */ on_send_guild_card, - /* 07 */ on_symbol_chat, - /* 08 */ nullptr, - /* 09 */ nullptr, - /* 0A */ on_enemy_hit, - /* 0B */ on_forward_check_size_game, - /* 0C */ on_forward_check_size_game, // Add condition (poison/slow/etc.) - /* 0D */ on_forward_check_size_game, // Remove condition (poison/slow/etc.) - /* 0E */ nullptr, - /* 0F */ nullptr, - /* 10 */ nullptr, - /* 11 */ nullptr, - /* 12 */ on_forward_check_size_game, // Dragon actions - /* 13 */ on_forward_check_size_game, // De Rol Le actions - /* 14 */ on_forward_check_size_game, - /* 15 */ on_forward_check_size_game, // Vol Opt actions - /* 16 */ on_forward_check_size_game, // Vol Opt actions - /* 17 */ on_forward_check_size_game, - /* 18 */ on_forward_check_size_game, - /* 19 */ on_forward_check_size_game, // Dark Falz actions - /* 1A */ nullptr, - /* 1B */ nullptr, - /* 1C */ on_forward_check_size_game, - /* 1D */ nullptr, - /* 1E */ nullptr, - /* 1F */ on_forward_check_size, - /* 20 */ on_forward_check_size, - /* 21 */ on_change_area, // Inter-level warp - /* 22 */ on_forward_check_size_client, // Set player visibility - /* 23 */ on_set_player_visibility, // Set player visibility - /* 24 */ on_forward_check_size_game, - /* 25 */ on_equip_unequip_item, // Equip item - /* 26 */ on_equip_unequip_item, // Unequip item - /* 27 */ on_use_item, - /* 28 */ on_forward_check_size_game, // Feed MAG - /* 29 */ on_destroy_inventory_item, // Delete item (via bank deposit / sale / feeding MAG) - /* 2A */ on_player_drop_item, - /* 2B */ on_create_inventory_item, // Create inventory item (e.g. from tekker or bank withdrawal) - /* 2C */ on_forward_check_size, // Talk to NPC - /* 2D */ on_forward_check_size, // Done talking to NPC - /* 2E */ nullptr, - /* 2F */ on_hit_by_enemy, - /* 30 */ on_forward_check_size_game, // Level up - /* 31 */ on_forward_check_size_game, // Medical center - /* 32 */ on_forward_check_size_game, // Medical center - /* 33 */ on_forward_check_size_game, // Moon atomizer/Reverser - /* 34 */ nullptr, - /* 35 */ nullptr, - /* 36 */ on_forward_check_game, - /* 37 */ on_forward_check_size_game, // Photon blast - /* 38 */ nullptr, - /* 39 */ on_forward_check_size_game, // Photon blast ready - /* 3A */ on_forward_check_size_game, - /* 3B */ on_forward_check_size, - /* 3C */ nullptr, - /* 3D */ nullptr, - /* 3E */ on_movement, // Stop moving - /* 3F */ on_movement, // Set position (e.g. when materializing after warp) - /* 40 */ on_movement, // Walk - /* 41 */ nullptr, - /* 42 */ on_movement, // Run - /* 43 */ on_forward_check_size_client, - /* 44 */ on_forward_check_size_client, - /* 45 */ on_forward_check_size_client, - /* 46 */ on_attack_finished, - /* 47 */ on_cast_technique, - /* 48 */ on_cast_technique_finished, - /* 49 */ on_subtract_pb_energy, - /* 4A */ on_forward_check_size_client, - /* 4B */ on_hit_by_enemy, - /* 4C */ on_hit_by_enemy, - /* 4D */ on_forward_check_size_client, - /* 4E */ on_forward_check_size_client, - /* 4F */ on_forward_check_size_client, - /* 50 */ on_forward_check_size_client, - /* 51 */ nullptr, - /* 52 */ on_forward_check_size, // Toggle shop/bank interaction - /* 53 */ on_forward_check_size_game, - /* 54 */ nullptr, - /* 55 */ on_forward_check_size_client, // Intra-map warp - /* 56 */ on_forward_check_size_client, - /* 57 */ on_forward_check_size_client, - /* 58 */ on_forward_check_size_client, // Begin playing emote - /* 59 */ on_pick_up_item, // Item picked up - /* 5A */ on_pick_up_item_request, // Request to pick up item - /* 5B */ nullptr, - /* 5C */ nullptr, - /* 5D */ on_drop_partial_stack, // Drop meseta or stacked item - /* 5E */ on_buy_shop_item, // Buy item at shop - /* 5F */ on_box_or_enemy_item_drop, // Drop item from box/enemy - /* 60 */ on_enemy_drop_item_request, // Request for item drop (handled by the server on BB) - /* 61 */ on_forward_check_size_game, // Feed mag - /* 62 */ nullptr, - /* 63 */ on_destroy_ground_item, // Destroy an item on the ground (used when too many items have been dropped) - /* 64 */ nullptr, - /* 65 */ nullptr, - /* 66 */ on_forward_check_size_game, // Use star atomizer - /* 67 */ on_forward_check_size_game, // Create enemy set - /* 68 */ on_forward_check_size_game, // Telepipe/Ryuker - /* 69 */ on_forward_check_size_game, - /* 6A */ on_forward_check_size_game, - /* 6B */ on_forward_check_game_loading, - /* 6C */ on_forward_check_game_loading, - /* 6D */ on_forward_check_game_loading, - /* 6E */ on_forward_check_game_loading, - /* 6F */ on_forward_check_game_loading, - /* 70 */ on_forward_check_game_loading, - /* 71 */ on_forward_check_game_loading, - /* 72 */ on_forward_check_game_loading, - /* 73 */ on_invalid, - /* 74 */ on_word_select, - /* 75 */ on_phase_setup, - /* 76 */ on_forward_check_size_game, // Enemy killed - /* 77 */ on_forward_check_size_game, // Sync quest data - /* 78 */ nullptr, - /* 79 */ on_forward_check_size, // Lobby 14/15 soccer game - /* 7A */ nullptr, - /* 7B */ nullptr, - /* 7C */ on_forward_check_size_game, - /* 7D */ on_forward_check_size_game, - /* 7E */ nullptr, - /* 7F */ nullptr, - /* 80 */ on_forward_check_size_game, // Trigger trap - /* 81 */ nullptr, - /* 82 */ nullptr, - /* 83 */ on_forward_check_size_game, // Place trap - /* 84 */ on_forward_check_size_game, - /* 85 */ on_forward_check_size_game, - /* 86 */ on_forward_check_size_game, // Hit destructible wall - /* 87 */ on_forward_check_size_game, // Shrink character - /* 88 */ on_forward_check_size_game, - /* 89 */ on_forward_check_size_game, - /* 8A */ on_forward_check_size_game, - /* 8B */ nullptr, - /* 8C */ nullptr, - /* 8D */ on_forward_check_size_client, - /* 8E */ nullptr, - /* 8F */ nullptr, - /* 90 */ nullptr, - /* 91 */ on_forward_check_size_game, - /* 92 */ nullptr, - /* 93 */ on_forward_check_size_game, // Timed switch activated - /* 94 */ on_forward_check_size_game, // Warp (the $warp chat command is implemented using this) - /* 95 */ nullptr, - /* 96 */ nullptr, - /* 97 */ nullptr, - /* 98 */ nullptr, - /* 99 */ nullptr, - /* 9A */ on_forward_check_size_game, // Update player stat ($infhp/$inftp are implemented using this command) - /* 9B */ nullptr, - /* 9C */ on_forward_check_size_game, - /* 9D */ nullptr, - /* 9E */ nullptr, - /* 9F */ on_forward_check_size_game, // Gal Gryphon actions - /* A0 */ on_forward_check_size_game, // Gal Gryphon actions - /* A1 */ on_forward_check_size_game, // Part of revive process. Occurs right after revive command, function unclear. - /* A2 */ on_box_drop_item_request, // Request for item drop from box (handled by server on BB) - /* A3 */ on_forward_check_size_game, // Episode 2 boss actions - /* A4 */ on_forward_check_size_game, // Olga Flow phase 1 actions - /* A5 */ on_forward_check_size_game, // Olga Flow phase 2 actions - /* A6 */ on_forward_check_size, // Trade proposal - /* A7 */ nullptr, - /* A8 */ on_forward_check_size_game, // Gol Dragon actions - /* A9 */ on_forward_check_size_game, // Barba Ray actions - /* AA */ on_forward_check_size_game, // Episode 2 boss actions - /* AB */ on_forward_check_size_client, // Create lobby chair - /* AC */ nullptr, - /* AD */ on_forward_check_size_game, // Olga Flow phase 2 subordinate boss actions - /* AE */ on_forward_check_size_client, - /* AF */ on_forward_check_size_client, // Turn in lobby chair - /* B0 */ on_forward_check_size_client, // Move in lobby chair - /* B1 */ nullptr, - /* B2 */ nullptr, - /* B3 */ on_ep3_battle_subs, - /* B4 */ on_ep3_battle_subs, - /* B5 */ on_open_shop_bb_or_ep3_battle_subs, // BB shop request - /* B6 */ nullptr, // BB shop contents (server->client only) - /* B7 */ on_buy_shop_item_bb, - /* B8 */ on_identify_item_bb, - /* B9 */ nullptr, - /* BA */ on_accept_identify_item_bb, - /* BB */ on_open_bank_bb_or_card_trade_counter_ep3, - /* BC */ on_forward_check_size_ep3_game, // BB bank contents (server->client only), Ep3 card trade sequence - /* BD */ on_bank_action_bb, - /* BE */ on_forward_check_size, // BB create inventory item (server->client only), Ep3 sound chat - /* BF */ on_forward_check_size_ep3_lobby, // Ep3 change music, also BB give EXP (BB usage is server->client only) - /* C0 */ on_sell_item_at_shop_bb, - /* C1 */ nullptr, - /* C2 */ nullptr, - /* C3 */ on_drop_partial_stack_bb, // Split stacked item - not sent if entire stack is dropped - /* C4 */ on_sort_inventory_bb, - /* C5 */ on_medical_center_bb, - /* C6 */ nullptr, - /* C7 */ nullptr, - /* C8 */ on_enemy_killed, - /* C9 */ nullptr, - /* CA */ nullptr, - /* CB */ nullptr, - /* CC */ nullptr, - /* CD */ nullptr, - /* CE */ nullptr, - /* CF */ on_forward_check_size_game, - /* D0 */ nullptr, - /* D1 */ nullptr, - /* D2 */ nullptr, - /* D3 */ nullptr, - /* D4 */ nullptr, - /* D5 */ nullptr, - /* D6 */ nullptr, - /* D7 */ nullptr, - /* D8 */ nullptr, - /* D9 */ nullptr, - /* DA */ nullptr, - /* DB */ nullptr, - /* DC */ nullptr, - /* DD */ nullptr, - /* DE */ nullptr, - /* DF */ nullptr, - /* E0 */ nullptr, - /* E1 */ nullptr, - /* E2 */ nullptr, - /* E3 */ nullptr, - /* E4 */ nullptr, - /* E5 */ nullptr, - /* E6 */ nullptr, - /* E7 */ nullptr, - /* E8 */ nullptr, - /* E9 */ nullptr, - /* EA */ nullptr, - /* EB */ nullptr, - /* EC */ nullptr, - /* ED */ nullptr, - /* EE */ nullptr, - /* EF */ nullptr, - /* F0 */ nullptr, - /* F1 */ nullptr, - /* F2 */ nullptr, - /* F3 */ nullptr, - /* F4 */ nullptr, - /* F5 */ nullptr, - /* F6 */ nullptr, - /* F7 */ nullptr, - /* F8 */ nullptr, - /* F9 */ nullptr, - /* FA */ nullptr, - /* FB */ nullptr, - /* FC */ nullptr, - /* FD */ nullptr, - /* FE */ nullptr, - /* FF */ nullptr, + /* 00 */ on_invalid, + /* 01 */ nullptr, + /* 02 */ nullptr, + /* 03 */ nullptr, + /* 04 */ nullptr, + /* 05 */ on_switch_state_changed, + /* 06 */ on_send_guild_card, + /* 07 */ on_symbol_chat, + /* 08 */ nullptr, + /* 09 */ nullptr, + /* 0A */ on_enemy_hit, + /* 0B */ on_forward_check_size_game, + /* 0C */ on_forward_check_size_game, // Add condition (poison/slow/etc.) + /* 0D */ on_forward_check_size_game, // Remove condition (poison/slow/etc.) + /* 0E */ nullptr, + /* 0F */ nullptr, + /* 10 */ nullptr, + /* 11 */ nullptr, + /* 12 */ on_forward_check_size_game, // Dragon actions + /* 13 */ on_forward_check_size_game, // De Rol Le actions + /* 14 */ on_forward_check_size_game, + /* 15 */ on_forward_check_size_game, // Vol Opt actions + /* 16 */ on_forward_check_size_game, // Vol Opt actions + /* 17 */ on_forward_check_size_game, + /* 18 */ on_forward_check_size_game, + /* 19 */ on_forward_check_size_game, // Dark Falz actions + /* 1A */ nullptr, + /* 1B */ nullptr, + /* 1C */ on_forward_check_size_game, + /* 1D */ nullptr, + /* 1E */ nullptr, + /* 1F */ on_forward_check_size, + /* 20 */ on_forward_check_size, + /* 21 */ on_change_area, // Inter-level warp + /* 22 */ on_forward_check_size_client, // Set player visibility + /* 23 */ on_set_player_visibility, // Set player visibility + /* 24 */ on_forward_check_size_game, + /* 25 */ on_equip_unequip_item, // Equip item + /* 26 */ on_equip_unequip_item, // Unequip item + /* 27 */ on_use_item, + /* 28 */ on_forward_check_size_game, // Feed MAG + /* 29 */ on_destroy_inventory_item, // Delete item (via bank deposit / sale / feeding MAG) + /* 2A */ on_player_drop_item, + /* 2B */ on_create_inventory_item, // Create inventory item (e.g. from tekker or bank withdrawal) + /* 2C */ on_forward_check_size, // Talk to NPC + /* 2D */ on_forward_check_size, // Done talking to NPC + /* 2E */ nullptr, + /* 2F */ on_hit_by_enemy, + /* 30 */ on_forward_check_size_game, // Level up + /* 31 */ on_forward_check_size_game, // Medical center + /* 32 */ on_forward_check_size_game, // Medical center + /* 33 */ on_forward_check_size_game, // Moon atomizer/Reverser + /* 34 */ nullptr, + /* 35 */ nullptr, + /* 36 */ on_forward_check_game, + /* 37 */ on_forward_check_size_game, // Photon blast + /* 38 */ nullptr, + /* 39 */ on_forward_check_size_game, // Photon blast ready + /* 3A */ on_forward_check_size_game, + /* 3B */ on_forward_check_size, + /* 3C */ nullptr, + /* 3D */ nullptr, + /* 3E */ on_movement, // Stop moving + /* 3F */ on_movement, // Set position (e.g. when materializing after warp) + /* 40 */ on_movement, // Walk + /* 41 */ nullptr, + /* 42 */ on_movement, // Run + /* 43 */ on_forward_check_size_client, + /* 44 */ on_forward_check_size_client, + /* 45 */ on_forward_check_size_client, + /* 46 */ on_attack_finished, + /* 47 */ on_cast_technique, + /* 48 */ on_cast_technique_finished, + /* 49 */ on_subtract_pb_energy, + /* 4A */ on_forward_check_size_client, + /* 4B */ on_hit_by_enemy, + /* 4C */ on_hit_by_enemy, + /* 4D */ on_forward_check_size_client, + /* 4E */ on_forward_check_size_client, + /* 4F */ on_forward_check_size_client, + /* 50 */ on_forward_check_size_client, + /* 51 */ nullptr, + /* 52 */ on_forward_check_size, // Toggle shop/bank interaction + /* 53 */ on_forward_check_size_game, + /* 54 */ nullptr, + /* 55 */ on_forward_check_size_client, // Intra-map warp + /* 56 */ on_forward_check_size_client, + /* 57 */ on_forward_check_size_client, + /* 58 */ on_forward_check_size_client, // Begin playing emote + /* 59 */ on_pick_up_item, // Item picked up + /* 5A */ on_pick_up_item_request, // Request to pick up item + /* 5B */ nullptr, + /* 5C */ nullptr, + /* 5D */ on_drop_partial_stack, // Drop meseta or stacked item + /* 5E */ on_buy_shop_item, // Buy item at shop + /* 5F */ on_box_or_enemy_item_drop, // Drop item from box/enemy + /* 60 */ on_enemy_drop_item_request, // Request for item drop (handled by the server on BB) + /* 61 */ on_forward_check_size_game, // Feed mag + /* 62 */ nullptr, + /* 63 */ on_destroy_ground_item, // Destroy an item on the ground (used when too many items have been dropped) + /* 64 */ nullptr, + /* 65 */ nullptr, + /* 66 */ on_forward_check_size_game, // Use star atomizer + /* 67 */ on_forward_check_size_game, // Create enemy set + /* 68 */ on_forward_check_size_game, // Telepipe/Ryuker + /* 69 */ on_forward_check_size_game, + /* 6A */ on_forward_check_size_game, + /* 6B */ on_forward_check_game_loading, + /* 6C */ on_forward_check_game_loading, + /* 6D */ on_forward_check_game_loading, + /* 6E */ on_forward_check_game_loading, + /* 6F */ on_forward_check_game_loading, + /* 70 */ on_forward_check_game_loading, + /* 71 */ on_forward_check_game_loading, + /* 72 */ on_forward_check_game_loading, + /* 73 */ on_invalid, + /* 74 */ on_word_select, + /* 75 */ on_phase_setup, + /* 76 */ on_forward_check_size_game, // Enemy killed + /* 77 */ on_forward_check_size_game, // Sync quest data + /* 78 */ nullptr, + /* 79 */ on_forward_check_size, // Lobby 14/15 soccer game + /* 7A */ nullptr, + /* 7B */ nullptr, + /* 7C */ on_forward_check_size_game, + /* 7D */ on_forward_check_size_game, + /* 7E */ nullptr, + /* 7F */ nullptr, + /* 80 */ on_forward_check_size_game, // Trigger trap + /* 81 */ nullptr, + /* 82 */ nullptr, + /* 83 */ on_forward_check_size_game, // Place trap + /* 84 */ on_forward_check_size_game, + /* 85 */ on_forward_check_size_game, + /* 86 */ on_forward_check_size_game, // Hit destructible wall + /* 87 */ on_forward_check_size_game, // Shrink character + /* 88 */ on_forward_check_size_game, + /* 89 */ on_forward_check_size_game, + /* 8A */ on_forward_check_size_game, + /* 8B */ nullptr, + /* 8C */ nullptr, + /* 8D */ on_forward_check_size_client, + /* 8E */ nullptr, + /* 8F */ nullptr, + /* 90 */ nullptr, + /* 91 */ on_forward_check_size_game, + /* 92 */ nullptr, + /* 93 */ on_forward_check_size_game, // Timed switch activated + /* 94 */ on_forward_check_size_game, // Warp (the $warp chat command is implemented using this) + /* 95 */ nullptr, + /* 96 */ nullptr, + /* 97 */ nullptr, + /* 98 */ nullptr, + /* 99 */ nullptr, + /* 9A */ on_forward_check_size_game, // Update player stat ($infhp/$inftp are implemented using this command) + /* 9B */ nullptr, + /* 9C */ on_forward_check_size_game, + /* 9D */ nullptr, + /* 9E */ nullptr, + /* 9F */ on_forward_check_size_game, // Gal Gryphon actions + /* A0 */ on_forward_check_size_game, // Gal Gryphon actions + /* A1 */ on_forward_check_size_game, // Part of revive process. Occurs right after revive command, function unclear. + /* A2 */ on_box_drop_item_request, // Request for item drop from box (handled by server on BB) + /* A3 */ on_forward_check_size_game, // Episode 2 boss actions + /* A4 */ on_forward_check_size_game, // Olga Flow phase 1 actions + /* A5 */ on_forward_check_size_game, // Olga Flow phase 2 actions + /* A6 */ on_forward_check_size, // Trade proposal + /* A7 */ nullptr, + /* A8 */ on_forward_check_size_game, // Gol Dragon actions + /* A9 */ on_forward_check_size_game, // Barba Ray actions + /* AA */ on_forward_check_size_game, // Episode 2 boss actions + /* AB */ on_forward_check_size_client, // Create lobby chair + /* AC */ nullptr, + /* AD */ on_forward_check_size_game, // Olga Flow phase 2 subordinate boss actions + /* AE */ on_forward_check_size_client, + /* AF */ on_forward_check_size_client, // Turn in lobby chair + /* B0 */ on_forward_check_size_client, // Move in lobby chair + /* B1 */ nullptr, + /* B2 */ nullptr, + /* B3 */ on_ep3_battle_subs, + /* B4 */ on_ep3_battle_subs, + /* B5 */ on_open_shop_bb_or_ep3_battle_subs, // BB shop request + /* B6 */ nullptr, // BB shop contents (server->client only) + /* B7 */ on_buy_shop_item_bb, + /* B8 */ on_identify_item_bb, + /* B9 */ nullptr, + /* BA */ on_accept_identify_item_bb, + /* BB */ on_open_bank_bb_or_card_trade_counter_ep3, + /* BC */ on_forward_check_size_ep3_game, // BB bank contents (server->client only), Ep3 card trade sequence + /* BD */ on_bank_action_bb, + /* BE */ on_forward_check_size, // BB create inventory item (server->client only), Ep3 sound chat + /* BF */ on_forward_check_size_ep3_lobby, // Ep3 change music, also BB give EXP (BB usage is server->client only) + /* C0 */ on_sell_item_at_shop_bb, + /* C1 */ nullptr, + /* C2 */ nullptr, + /* C3 */ on_drop_partial_stack_bb, // Split stacked item - not sent if entire stack is dropped + /* C4 */ on_sort_inventory_bb, + /* C5 */ on_medical_center_bb, + /* C6 */ nullptr, + /* C7 */ nullptr, + /* C8 */ on_enemy_killed, + /* C9 */ nullptr, + /* CA */ nullptr, + /* CB */ nullptr, + /* CC */ nullptr, + /* CD */ nullptr, + /* CE */ nullptr, + /* CF */ on_forward_check_size_game, + /* D0 */ nullptr, + /* D1 */ nullptr, + /* D2 */ nullptr, + /* D3 */ nullptr, + /* D4 */ nullptr, + /* D5 */ nullptr, + /* D6 */ nullptr, + /* D7 */ nullptr, + /* D8 */ nullptr, + /* D9 */ nullptr, + /* DA */ nullptr, + /* DB */ nullptr, + /* DC */ nullptr, + /* DD */ nullptr, + /* DE */ nullptr, + /* DF */ nullptr, + /* E0 */ nullptr, + /* E1 */ nullptr, + /* E2 */ nullptr, + /* E3 */ nullptr, + /* E4 */ nullptr, + /* E5 */ nullptr, + /* E6 */ nullptr, + /* E7 */ nullptr, + /* E8 */ nullptr, + /* E9 */ nullptr, + /* EA */ nullptr, + /* EB */ nullptr, + /* EC */ nullptr, + /* ED */ nullptr, + /* EE */ nullptr, + /* EF */ nullptr, + /* F0 */ nullptr, + /* F1 */ nullptr, + /* F2 */ nullptr, + /* F3 */ nullptr, + /* F4 */ nullptr, + /* F5 */ nullptr, + /* F6 */ nullptr, + /* F7 */ nullptr, + /* F8 */ nullptr, + /* F9 */ nullptr, + /* FA */ nullptr, + /* FB */ nullptr, + /* FC */ nullptr, + /* FD */ nullptr, + /* FE */ nullptr, + /* FF */ nullptr, }; void on_subcommand(shared_ptr s, shared_ptr l, - shared_ptr c, uint8_t command, uint8_t flag, const string& data) { + shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (data.empty()) { throw runtime_error("game command is empty"); } diff --git a/src/ReceiveSubcommands.hh b/src/ReceiveSubcommands.hh index 6c9aa383..2333e555 100644 --- a/src/ReceiveSubcommands.hh +++ b/src/ReceiveSubcommands.hh @@ -1,15 +1,13 @@ #include -#include "PSOProtocol.hh" #include "Client.hh" #include "Lobby.hh" -#include "Client.hh" +#include "PSOProtocol.hh" #include "ServerState.hh" - - -void on_subcommand(std::shared_ptr s, - std::shared_ptr l, std::shared_ptr c, uint8_t command, - uint8_t flag, const std::string& data); +void on_subcommand( + std::shared_ptr s, std::shared_ptr l, + std::shared_ptr c, uint8_t command, uint8_t flag, + const std::string& data); bool subcommand_is_implemented(uint8_t which); diff --git a/src/ReplaySession.cc b/src/ReplaySession.cc index be5a57bb..9c32250a 100644 --- a/src/ReplaySession.cc +++ b/src/ReplaySession.cc @@ -5,19 +5,17 @@ #include #include "Loggers.hh" -#include "Shell.hh" #include "Server.hh" +#include "Shell.hh" using namespace std; - - ReplaySession::Event::Event(Type type, uint64_t client_id, size_t line_num) - : type(type), - client_id(client_id), - allow_size_disparity(false), - complete(false), - line_num(line_num) { } + : type(type), + client_id(client_id), + allow_size_disparity(false), + complete(false), + line_num(line_num) {} string ReplaySession::Event::str() const { string ret; @@ -40,27 +38,23 @@ string ReplaySession::Event::str() const { return ret; } - - ReplaySession::Client::Client( ReplaySession* session, uint64_t id, uint16_t port, GameVersion version) - : id(id), - port(port), - version(version), - channel( - this->version, - &ReplaySession::dispatch_on_command_received, - &ReplaySession::dispatch_on_error, - session, - string_printf("R-%" PRIX64, this->id)) { } + : id(id), + port(port), + version(version), + channel( + this->version, + &ReplaySession::dispatch_on_command_received, + &ReplaySession::dispatch_on_error, + session, + string_printf("R-%" PRIX64, this->id)) {} string ReplaySession::Client::str() const { return string_printf("Client[%" PRIu64 ", T-%hu, %s]", this->id, this->port, name_for_version(this->version)); } - - shared_ptr ReplaySession::create_event( Event::Type type, shared_ptr c, size_t line_num) { shared_ptr event(new Event(type, c->id, line_num)); @@ -242,10 +236,12 @@ void ReplaySession::apply_default_mask(shared_ptr ev) { uint8_t command; if (version == GameVersion::PC) { command = check_size_t( - ev->data, sizeof(PSOCommandHeaderPC), 0xFFFF).command; + ev->data, sizeof(PSOCommandHeaderPC), 0xFFFF) + .command; } else { // V3 command = check_size_t( - ev->data, sizeof(PSOCommandHeaderDCV3), 0xFFFF).command; + ev->data, sizeof(PSOCommandHeaderDCV3), 0xFFFF) + .command; } switch (command) { case 0x02: @@ -335,7 +331,8 @@ void ReplaySession::apply_default_mask(shared_ptr ev) { } case GameVersion::BB: { uint16_t command = check_size_t( - ev->data, sizeof(PSOCommandHeaderBB), 0xFFFF).command; + ev->data, sizeof(PSOCommandHeaderBB), 0xFFFF) + .command; switch (command) { case 0x0003: { auto& mask = check_size_t( @@ -380,14 +377,14 @@ ReplaySession::ReplaySession( shared_ptr state, const string& required_access_key, const string& required_password) - : state(state), - required_access_key(required_access_key), - required_password(required_password), - base(base), - commands_sent(0), - bytes_sent(0), - commands_received(0), - bytes_received(0) { + : state(state), + required_access_key(required_access_key), + required_password(required_password), + base(base), + commands_sent(0), + bytes_sent(0), + commands_received(0), + bytes_received(0) { shared_ptr parsing_command = nullptr; size_t line_num = 0; @@ -419,7 +416,7 @@ ReplaySession::ReplaySession( if (parsing_command->type == Event::Type::RECEIVE) { this->apply_default_mask(parsing_command); } else if (parsing_command->type == Event::Type::SEND) { - this->check_for_password(parsing_command); + this->check_for_password(parsing_command); } parsing_command = nullptr; } diff --git a/src/ReplaySession.hh b/src/ReplaySession.hh index 33b75925..573d8472 100644 --- a/src/ReplaySession.hh +++ b/src/ReplaySession.hh @@ -9,10 +9,8 @@ #include #include "Channel.hh" -#include "Version.hh" #include "ServerState.hh" - - +#include "Version.hh" class ReplaySession { public: diff --git a/src/SaveFileFormats.cc b/src/SaveFileFormats.cc index 8a7e4ca0..8c70f5f6 100644 --- a/src/SaveFileFormats.cc +++ b/src/SaveFileFormats.cc @@ -1,12 +1,10 @@ #include "SaveFileFormats.hh" -#include #include +#include using namespace std; - - ShuffleTables::ShuffleTables(PSOV2Encryption& crypt) { for (size_t x = 0; x < 0x100; x++) { this->forward_table[x] = x; @@ -48,8 +46,6 @@ void ShuffleTables::shuffle(void* vdest, const void* vsrc, size_t size, bool rev memcpy(&dest[size & 0xFFFFFF00], &src[size & 0xFFFFFF00], size & 0xFF); } - - bool PSOGCIFileHeader::checksum_correct() const { uint32_t cs = crc32(&this->game_name, this->game_name.bytes()); cs = crc32(&this->embedded_seed, sizeof(this->embedded_seed), cs); @@ -88,8 +84,6 @@ bool PSOGCIFileHeader::is_ep3() const { return (this->game_id[2] == 'S'); } - - uint32_t compute_psogc_timestamp( uint16_t year, uint8_t month, diff --git a/src/SaveFileFormats.hh b/src/SaveFileFormats.hh index da21c048..f6f4b4de 100644 --- a/src/SaveFileFormats.hh +++ b/src/SaveFileFormats.hh @@ -2,17 +2,15 @@ #include -#include #include #include -#include #include +#include +#include #include "PSOEncryption.hh" -#include "Text.hh" #include "Player.hh" - - +#include "Text.hh" struct ShuffleTables { uint8_t forward_table[0x100]; @@ -25,8 +23,6 @@ struct ShuffleTables { void shuffle(void* vdest, const void* vsrc, size_t size, bool reverse) const; }; - - struct PSOGCIFileHeader { // Every PSOGC save file begins with a PSOGCIFileHeader. The first 0x40 bytes // of this structure are the .gci file header; the remaining bytes after that @@ -277,8 +273,6 @@ struct PSOGCGuildCardFile { /* E28C */ } __attribute__((packed)); - - template std::string decrypt_gci_or_vms_v2_data_section( const void* data_section, size_t size, uint32_t round1_seed) { @@ -357,8 +351,6 @@ std::string encrypt_gci_fixed_size_file_data_section( &encrypted, sizeof(StructT), round1_seed); } - - uint32_t compute_psogc_timestamp( uint16_t year, uint8_t month, diff --git a/src/SendCommands.cc b/src/SendCommands.cc index ef60623e..fedd99a5 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -1,73 +1,69 @@ #include "SendCommands.hh" +#include #include #include -#include #include #include +#include #include #include #include -#include -#include "PSOProtocol.hh" #include "CommandFormats.hh" #include "Compression.hh" #include "FileContentsCache.hh" -#include "Text.hh" +#include "PSOProtocol.hh" #include "StaticGameData.hh" +#include "Text.hh" using namespace std; - - extern const char* QUEST_BARRIER_DISCONNECT_HOOK_NAME; extern const char* CARD_AUCTION_DISCONNECT_HOOK_NAME; const unordered_set v2_crypt_initial_client_commands({ - 0x00260088, // (17) DCNTE license check - 0x00B0008B, // (02) DCNTE login - 0x0114008B, // (02) DCNTE extended login - 0x00280090, // (17) DCv1 license check - 0x00B00093, // (02) DCv1 login - 0x01140093, // (02) DCv1 extended login - 0x00E0009A, // (17) DCv2/GCNTE license check - 0x00CC009D, // (02) DCv2/GCNTE login - 0x00CC019D, // (02) DCv2/GCNTE login (UDP off) - 0x0130009D, // (02) DCv2/GCNTE extended login - 0x0130019D, // (02) DCv2/GCNTE extended login (UDP off) - // Note: PSO PC initial commands are not listed here because we don't use a - // detector encryption for PSO PC (instead, we use the split reconnect command - // to send PC to a different port). + 0x00260088, // (17) DCNTE license check + 0x00B0008B, // (02) DCNTE login + 0x0114008B, // (02) DCNTE extended login + 0x00280090, // (17) DCv1 license check + 0x00B00093, // (02) DCv1 login + 0x01140093, // (02) DCv1 extended login + 0x00E0009A, // (17) DCv2/GCNTE license check + 0x00CC009D, // (02) DCv2/GCNTE login + 0x00CC019D, // (02) DCv2/GCNTE login (UDP off) + 0x0130009D, // (02) DCv2/GCNTE extended login + 0x0130019D, // (02) DCv2/GCNTE extended login (UDP off) + // Note: PSO PC initial commands are not listed here because we don't use a + // detector encryption for PSO PC (instead, we use the split reconnect command + // to send PC to a different port). }); const unordered_set v3_crypt_initial_client_commands({ - 0x00E000DB, // (17) GC/XB license check - 0x00EC009E, // (02) GC login - 0x00EC019E, // (02) GC login (UDP off) - 0x0150009E, // (02) GC extended login - 0x0150019E, // (02) GC extended login (UDP off) - 0x0130009E, // (02) XB login - 0x0130019E, // (02) XB login (UDP off) - 0x0194009E, // (02) XB extended login - 0x0194019E, // (02) XB extended login (UDP off) + 0x00E000DB, // (17) GC/XB license check + 0x00EC009E, // (02) GC login + 0x00EC019E, // (02) GC login (UDP off) + 0x0150009E, // (02) GC extended login + 0x0150019E, // (02) GC extended login (UDP off) + 0x0130009E, // (02) XB login + 0x0130019E, // (02) XB login (UDP off) + 0x0194009E, // (02) XB extended login + 0x0194019E, // (02) XB extended login (UDP off) }); const unordered_set bb_crypt_initial_client_commands({ - string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8), - string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8), - string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8), + string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8), + string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8), + string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8), }); - - void send_command(shared_ptr c, uint16_t command, uint32_t flag, - const void* data, size_t size) { + const void* data, size_t size) { c->channel.send(command, flag, data, size); } void send_command_excluding_client(shared_ptr l, shared_ptr c, - uint16_t command, uint32_t flag, const void* data, size_t size) { + uint16_t command, uint32_t flag, const void* data, size_t size) { for (auto& client : l->clients) { if (!client || (client == c)) { continue; @@ -77,7 +73,7 @@ void send_command_excluding_client(shared_ptr l, shared_ptr c, } void send_command_if_not_loading(shared_ptr l, - uint16_t command, uint32_t flag, const void* data, size_t size) { + uint16_t command, uint32_t flag, const void* data, size_t size) { for (auto& client : l->clients) { if (!client || (client->flags & Client::Flag::LOADING)) { continue; @@ -87,12 +83,12 @@ void send_command_if_not_loading(shared_ptr l, } void send_command(shared_ptr l, uint16_t command, uint32_t flag, - const void* data, size_t size) { + const void* data, size_t size) { send_command_excluding_client(l, nullptr, command, flag, data, size); } void send_command(shared_ptr s, uint16_t command, uint32_t flag, - const void* data, size_t size) { + const void* data, size_t size) { for (auto& l : s->all_lobbies()) { send_command(l, command, flag, data, size); } @@ -123,8 +119,6 @@ void send_command_with_header(Channel& ch, const void* data, size_t size) { } } - - static const char* anti_copyright = "This server is in no way affiliated, sponsored, or supported by SEGA Enterprises or SONICTEAM. The preceding message exists only to remain compatible with programs that expect it."; static const char* dc_port_map_copyright = "DreamCast Port Map. Copyright SEGA Enterprises. 1999"; static const char* dc_lobby_server_copyright = "DreamCast Lobby Server. Copyright SEGA Enterprises. 1999"; @@ -138,7 +132,8 @@ prepare_server_init_contents_console( bool initial_connection = (flags & SendServerInitFlag::IS_INITIAL_CONNECTION); S_ServerInitWithAfterMessage_DC_PC_V3_02_17_91_9B<0xB4> cmd; cmd.basic_cmd.copyright = initial_connection - ? dc_port_map_copyright : dc_lobby_server_copyright; + ? dc_port_map_copyright + : dc_lobby_server_copyright; cmd.basic_cmd.server_key = server_key; cmd.basic_cmd.client_key = client_key; cmd.after_message = anti_copyright; @@ -189,7 +184,7 @@ prepare_server_init_contents_bb( } void send_server_init_bb(shared_ptr s, shared_ptr c, - uint8_t flags) { + uint8_t flags) { bool use_secondary_message = (flags & SendServerInitFlag::USE_SECONDARY_MESSAGE); parray server_key; parray client_key; @@ -245,8 +240,6 @@ void send_server_init( } } - - void send_update_client_config(shared_ptr c) { S_UpdateClientConfig_DC_PC_V3_04 cmd; cmd.player_tag = 0x00010000; @@ -255,8 +248,6 @@ void send_update_client_config(shared_ptr c) { send_command_t(c, 0x04, 0x00, cmd); } - - template void send_quest_open_file_t( shared_ptr c, @@ -396,15 +387,13 @@ void send_function_call( ch.send(0xB2, index, w.str()); } - - void send_reconnect(shared_ptr c, uint32_t address, uint16_t port) { S_Reconnect_19 cmd = {{address, port, 0}}; send_command_t(c, (c->version() == GameVersion::PATCH) ? 0x14 : 0x19, 0x00, cmd); } void send_pc_console_split_reconnect(shared_ptr c, uint32_t address, - uint16_t pc_port, uint16_t console_port) { + uint16_t pc_port, uint16_t console_port) { S_ReconnectSplit_19 cmd; cmd.pc_address = address; cmd.pc_port = pc_port; @@ -416,8 +405,6 @@ void send_pc_console_split_reconnect(shared_ptr c, uint32_t address, send_command_t(c, 0x19, 0x00, cmd); } - - void send_client_init_bb(shared_ptr c, uint32_t error) { S_ClientInit_BB_00E6 cmd; cmd.error = error; @@ -434,7 +421,7 @@ void send_team_and_key_config_bb(shared_ptr c) { } void send_player_preview_bb(shared_ptr c, uint8_t player_index, - const PlayerDispDataBBPreview* preview) { + const PlayerDispDataBBPreview* preview) { if (!preview) { // no player exists @@ -475,15 +462,15 @@ void send_guild_card_chunk_bb(shared_ptr c, size_t chunk_index) { } static const vector stream_file_entries = { - "ItemMagEdit.prs", - "ItemPMT.prs", - "BattleParamEntry.dat", - "BattleParamEntry_on.dat", - "BattleParamEntry_lab.dat", - "BattleParamEntry_lab_on.dat", - "BattleParamEntry_ep4.dat", - "BattleParamEntry_ep4_on.dat", - "PlyLevelTbl.prs", + "ItemMagEdit.prs", + "ItemPMT.prs", + "BattleParamEntry.dat", + "BattleParamEntry_on.dat", + "BattleParamEntry_lab.dat", + "BattleParamEntry_lab_on.dat", + "BattleParamEntry_ep4.dat", + "BattleParamEntry_ep4_on.dat", + "PlyLevelTbl.prs", }; static FileContentsCache bb_stream_files_cache(3600000000ULL); @@ -523,19 +510,20 @@ void send_stream_file_index_bb(shared_ptr c) { } void send_stream_file_chunk_bb(shared_ptr c, uint32_t chunk_index) { - auto cache_result = bb_stream_files_cache.get("", +[](const string&) -> string { - size_t bytes = 0; - for (const auto& name : stream_file_entries) { - bytes += bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data->size(); - } + auto cache_result = bb_stream_files_cache.get( + "", +[](const string&) -> string { + size_t bytes = 0; + for (const auto& name : stream_file_entries) { + bytes += bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data->size(); + } - string ret; - ret.reserve(bytes); - for (const auto& name : stream_file_entries) { - ret += *bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data; - } - return ret; - }); + string ret; + ret.reserve(bytes); + for (const auto& name : stream_file_entries) { + ret += *bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data; + } + return ret; + }); const auto& contents = cache_result.file->data; S_StreamFileChunk_BB_02EB chunk_cmd; @@ -561,8 +549,6 @@ void send_complete_player_bb(shared_ptr c) { send_command_t(c, 0x00E7, 0x00000000, c->game_data.export_player_bb()); } - - //////////////////////////////////////////////////////////////////////////////// // patch functions @@ -596,13 +582,11 @@ void send_patch_file(shared_ptr c, shared_ptr f) { send_command_t(c, 0x08, 0x00, close_cmd); } - - //////////////////////////////////////////////////////////////////////////////// // message functions void send_text(Channel& ch, StringWriter& w, uint16_t command, - const u16string& text, bool should_add_color) { + const u16string& text, bool should_add_color) { if ((ch.version == GameVersion::DC) || (ch.version == GameVersion::GC) || (ch.version == GameVersion::XB)) { @@ -633,7 +617,7 @@ void send_text(Channel& ch, uint16_t command, const u16string& text, bool should } void send_header_text(Channel& ch, uint16_t command, - uint32_t guild_card_number, const u16string& text, bool should_add_color) { + uint32_t guild_card_number, const u16string& text, bool should_add_color) { StringWriter w; w.put(SC_TextHeader_01_06_11_B0_EE({0, guild_card_number})); send_text(ch, w, command, text, should_add_color); @@ -676,7 +660,7 @@ void send_lobby_name(shared_ptr c, const u16string& text) { } void send_quest_info(shared_ptr c, const u16string& text, - bool is_download_quest) { + bool is_download_quest) { send_text(c->channel, is_download_quest ? 0xA5 : 0xA3, text, true); } @@ -766,12 +750,12 @@ void send_chat_message(Channel& ch, const u16string& text, char private_flags) { } void send_chat_message(shared_ptr c, uint32_t from_guild_card_number, - const u16string& prepared_data) { + const u16string& prepared_data) { send_header_text(c->channel, 0x06, from_guild_card_number, prepared_data, false); } void send_chat_message(shared_ptr l, uint32_t from_guild_card_number, - const u16string& prepared_data) { + const u16string& prepared_data) { for (auto c : l->clients) { if (c) { send_header_text(c->channel, 0x06, from_guild_card_number, prepared_data, false); @@ -780,7 +764,7 @@ void send_chat_message(shared_ptr l, uint32_t from_guild_card_number, } void send_chat_message(shared_ptr c, uint32_t from_guild_card_number, - const u16string& from_name, const u16string& text, char private_flags) { + const u16string& from_name, const u16string& text, char private_flags) { auto data = prepare_chat_message(c->version(), from_name, text, private_flags); send_chat_message(c, from_guild_card_number, data); } @@ -816,7 +800,7 @@ void send_simple_mail_bb( } void send_simple_mail(shared_ptr c, uint32_t from_guild_card_number, - const u16string& from_name, const u16string& text) { + const u16string& from_name, const u16string& text) { switch (c->version()) { case GameVersion::DC: case GameVersion::GC: @@ -836,8 +820,6 @@ void send_simple_mail(shared_ptr c, uint32_t from_guild_card_number, } } - - //////////////////////////////////////////////////////////////////////////////// // info board @@ -866,8 +848,6 @@ void send_info_board(shared_ptr c, shared_ptr l) { } } - - template void send_card_search_result_t( shared_ptr s, @@ -892,13 +872,13 @@ void send_card_search_result_t( if (result_lobby->is_game()) { string encoded_lobby_name = encode_sjis(result_lobby->name); location_string = string_printf("%s,BLOCK01,%s", - encoded_lobby_name.c_str(), encoded_server_name.c_str()); + encoded_lobby_name.c_str(), encoded_server_name.c_str()); } else if (result_lobby->is_ep3()) { location_string = string_printf("BLOCK01-C%02" PRIu32 ",BLOCK01,%s", - result_lobby->lobby_id - 15, encoded_server_name.c_str()); + result_lobby->lobby_id - 15, encoded_server_name.c_str()); } else { location_string = string_printf("BLOCK01-%02" PRIu32 ",BLOCK01,%s", - result_lobby->lobby_id, encoded_server_name.c_str()); + result_lobby->lobby_id, encoded_server_name.c_str()); } cmd.location_string = location_string; cmd.extension.lobby_refs[0].menu_id = MenuID::LOBBY; @@ -929,8 +909,6 @@ void send_card_search_result( } } - - template void send_guild_card_dc_pc_v3_t( Channel& ch, @@ -1019,8 +997,6 @@ void send_guild_card(shared_ptr c, shared_ptr source) { c->channel, guild_card_number, name, u"", description, section_id, char_class); } - - //////////////////////////////////////////////////////////////////////////////// // menus @@ -1091,7 +1067,7 @@ void send_menu_t( } void send_menu(shared_ptr c, const u16string& menu_name, - uint32_t menu_id, const vector& items, bool is_info_menu) { + uint32_t menu_id, const vector& items, bool is_info_menu) { if (c->version() == GameVersion::PC || c->version() == GameVersion::PATCH || c->version() == GameVersion::BB) { @@ -1101,8 +1077,6 @@ void send_menu(shared_ptr c, const u16string& menu_name, } } - - template void send_game_menu_t( shared_ptr c, @@ -1212,8 +1186,6 @@ void send_game_menu( } } - - template void send_quest_menu_t( shared_ptr c, @@ -1251,7 +1223,7 @@ void send_quest_menu_t( } void send_quest_menu(shared_ptr c, uint32_t menu_id, - const vector>& quests, bool is_download_menu) { + const vector>& quests, bool is_download_menu) { switch (c->version()) { case GameVersion::PC: send_quest_menu_t(c, menu_id, quests, is_download_menu); @@ -1272,7 +1244,7 @@ void send_quest_menu(shared_ptr c, uint32_t menu_id, } void send_quest_menu(shared_ptr c, uint32_t menu_id, - const vector& items, bool is_download_menu) { + const vector& items, bool is_download_menu) { switch (c->version()) { case GameVersion::PC: send_quest_menu_t(c, menu_id, items, is_download_menu); @@ -1317,8 +1289,6 @@ void send_lobby_list(shared_ptr c, shared_ptr s) { send_command_vt(c, 0x83, entries.size(), entries); } - - //////////////////////////////////////////////////////////////////////////////// // lobby joining @@ -1498,7 +1468,7 @@ void send_join_game_t(shared_ptr c, shared_ptr l) { template void send_join_lobby_t(shared_ptr c, shared_ptr l, - shared_ptr joining_client = nullptr) { + shared_ptr joining_client = nullptr) { uint8_t command; if (l->is_game()) { if (joining_client) { @@ -1616,7 +1586,7 @@ void send_join_lobby(shared_ptr c, shared_ptr l) { } void send_player_join_notification(shared_ptr c, - shared_ptr l, shared_ptr joining_client) { + shared_ptr l, shared_ptr joining_client) { switch (c->version()) { case GameVersion::PC: send_join_lobby_t(c, l, joining_client); @@ -1664,13 +1634,11 @@ void send_get_player_info(shared_ptr c) { } } - - //////////////////////////////////////////////////////////////////////////////// // Trade window void send_execute_item_trade(shared_ptr c, - const vector& items) { + const vector& items) { SC_TradeItems_D0_D3 cmd; if (items.size() > sizeof(cmd.items) / sizeof(cmd.items[0])) { throw logic_error("too many items in execute trade command"); @@ -1684,7 +1652,7 @@ void send_execute_item_trade(shared_ptr c, } void send_execute_card_trade(shared_ptr c, - const vector>& card_to_count) { + const vector>& card_to_count) { if (!(c->flags & Client::Flag::IS_EPISODE_3)) { throw logic_error("cannot send trade cards command to non-Ep3 client"); } @@ -1709,8 +1677,6 @@ void send_execute_card_trade(shared_ptr c, send_command_t(c, 0xEE, 0xD3, cmd); } - - //////////////////////////////////////////////////////////////////////////////// // arrows @@ -1741,8 +1707,6 @@ void send_resume_game(shared_ptr l, shared_ptr ready_client) { send_command_excluding_client(l, ready_client, 0x60, 0x00, &data, sizeof(be_uint32_t)); } - - //////////////////////////////////////////////////////////////////////////////// // Game/cheat commands @@ -1763,7 +1727,7 @@ static vector generate_stats_change_subcommands( } void send_player_stats_change(shared_ptr l, shared_ptr c, - PlayerStatsChange stat, uint32_t amount) { + PlayerStatsChange stat, uint32_t amount) { auto subs = generate_stats_change_subcommands(c->lobby_client_id, stat, amount); send_command_vt(l, (subs.size() > 0x400 / sizeof(G_UpdatePlayerStat_6x9A)) ? 0x6C : 0x60, 0x00, subs); } @@ -1789,48 +1753,46 @@ void send_ep3_change_music(Channel& ch, uint32_t song) { } void send_set_player_visibility(shared_ptr l, shared_ptr c, - bool visible) { + bool visible) { uint8_t subcmd = visible ? 0x23 : 0x22; uint16_t client_id = c->lobby_client_id; G_SetPlayerVisibility_6x22_6x23 cmd = {{subcmd, 0x01, client_id}}; send_command_t(l, 0x60, 0x00, cmd); } - - //////////////////////////////////////////////////////////////////////////////// // BB game commands void send_drop_item(Channel& ch, const ItemData& item, - bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) { + bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) { G_DropItem_PC_V3_BB_6x5F cmd = { {{0x5F, 0x0B, 0x0000}, area, from_enemy, request_id, x, z, 0, 0, item}, 0}; ch.send(0x60, 0x00, &cmd, sizeof(cmd)); } void send_drop_item(shared_ptr l, const ItemData& item, - bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) { + bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) { G_DropItem_PC_V3_BB_6x5F cmd = { {{0x5F, 0x0B, 0x0000}, area, from_enemy, request_id, x, z, 0, 0, item}, 0}; send_command_t(l, 0x60, 0x00, cmd); } void send_drop_stacked_item(Channel& ch, const ItemData& item, - uint8_t area, float x, float z) { + uint8_t area, float x, float z) { G_DropStackedItem_PC_V3_BB_6x5D cmd = { {{0x5D, 0x0A, 0x0000}, area, 0, x, z, item}, 0}; ch.send(0x60, 0x00, &cmd, sizeof(cmd)); } void send_drop_stacked_item(shared_ptr l, const ItemData& item, - uint8_t area, float x, float z) { + uint8_t area, float x, float z) { G_DropStackedItem_PC_V3_BB_6x5D cmd = { {{0x5D, 0x0A, 0x0000}, area, 0, x, z, item}, 0}; send_command_t(l, 0x60, 0x00, cmd); } void send_pick_up_item(shared_ptr l, shared_ptr c, - uint32_t item_id, uint8_t area) { + uint32_t item_id, uint8_t area) { uint16_t client_id = c->lobby_client_id; G_PickUpItem_6x59 cmd = { {0x59, 0x03, client_id}, client_id, area, item_id}; @@ -1840,7 +1802,7 @@ void send_pick_up_item(shared_ptr l, shared_ptr c, // Creates an item in a player's inventory (used for withdrawing items from the // bank) void send_create_inventory_item(shared_ptr l, shared_ptr c, - const ItemData& item) { + const ItemData& item) { uint16_t client_id = c->lobby_client_id; G_CreateInventoryItem_BB_6xBE cmd = {{0xBE, 0x07, client_id}, item, 0}; send_command_t(l, 0x60, 0x00, cmd); @@ -1848,7 +1810,7 @@ void send_create_inventory_item(shared_ptr l, shared_ptr c, // destroys an item void send_destroy_item(shared_ptr l, shared_ptr c, - uint32_t item_id, uint32_t amount) { + uint32_t item_id, uint32_t amount) { uint16_t client_id = c->lobby_client_id; G_DeleteInventoryItem_6x29 cmd = {{0x29, 0x03, client_id}, item_id, amount}; send_command_t(l, 0x60, 0x00, cmd); @@ -1857,7 +1819,7 @@ void send_destroy_item(shared_ptr l, shared_ptr c, // sends the player their bank data void send_bank(shared_ptr c) { vector items(c->game_data.player()->bank.items, - &c->game_data.player()->bank.items[c->game_data.player()->bank.num_items]); + &c->game_data.player()->bank.items[c->game_data.player()->bank.num_items]); uint32_t checksum = random_object(); G_BankContentsHeader_BB_6xBC cmd = { @@ -1874,11 +1836,11 @@ void send_shop(shared_ptr c, uint8_t shop_type) { const auto& contents = c->game_data.shop_contents.at(shop_type); G_ShopContents_BB_6xB6 cmd = { - {0xB6, static_cast(2 + (sizeof(ItemData) >> 2) * contents.size()), 0x0000}, - shop_type, - static_cast(contents.size()), - 0, - {}, + {0xB6, static_cast(2 + (sizeof(ItemData) >> 2) * contents.size()), 0x0000}, + shop_type, + static_cast(contents.size()), + 0, + {}, }; for (size_t x = 0; x < contents.size(); x++) { cmd.entries[x] = contents[x]; @@ -1916,15 +1878,13 @@ void send_level_up(shared_ptr l, shared_ptr c) { // gives a player EXP void send_give_experience(shared_ptr l, shared_ptr c, - uint32_t amount) { + uint32_t amount) { uint16_t client_id = c->lobby_client_id; G_GiveExperience_BB_6xBF cmd = { {0xBF, sizeof(G_GiveExperience_BB_6xBF) / 4, client_id}, amount}; send_command_t(l, 0x60, 0x00, cmd); } - - //////////////////////////////////////////////////////////////////////////////// // ep3 only commands @@ -2033,7 +1993,8 @@ void send_ep3_tournament_list( } auto& entry = cmd.entries[z]; entry.menu_id = is_for_spectator_team_create - ? MenuID::TOURNAMENTS_FOR_SPEC : MenuID::TOURNAMENTS; + ? MenuID::TOURNAMENTS_FOR_SPEC + : MenuID::TOURNAMENTS; entry.item_id = tourn->get_number(); // TODO: What does it mean for a tournament to be locked? Should we support // that? @@ -2043,7 +2004,8 @@ void send_ep3_tournament_list( // as long as the winners of the preceding matches have been determined. entry.state = (tourn->get_state() == Episode3::Tournament::State::REGISTRATION) - ? 0x00 : 0x05; + ? 0x00 + : 0x05; // TODO: Fill in cmd.start_time here when we implement scheduled starts. entry.name = tourn->get_name(); const auto& teams = tourn->all_teams(); @@ -2216,8 +2178,8 @@ void send_ep3_game_details(shared_ptr c, shared_ptr l) { flag = 0x04; } else if (primary_lobby && - primary_lobby->ep3_server_base && - primary_lobby->ep3_server_base->server->get_setup_phase() != Episode3::SetupPhase::REGISTRATION) { + primary_lobby->ep3_server_base && + primary_lobby->ep3_server_base->server->get_setup_phase() != Episode3::SetupPhase::REGISTRATION) { cmd.rules = primary_lobby->ep3_server_base->map_and_rules1->rules; flag = 0x01; @@ -2313,8 +2275,8 @@ void send_ep3_tournament_match_result( G_TournamentMatchResult_GC_Ep3_6xB4x51 cmd; cmd.match_description = (match == tourn->get_final_match()) - ? string_printf("(%s) Final match", tourn->get_name().c_str()) - : string_printf("(%s) Round %zu", tourn->get_name().c_str(), match->round_num); + ? string_printf("(%s) Final match", tourn->get_name().c_str()) + : string_printf("(%s) Round %zu", tourn->get_name().c_str(), match->round_num); cmd.names_entries[0].team_name = match->preceding_a->winner_team->name; write_player_names(cmd.names_entries[0], match->preceding_a->winner_team); cmd.names_entries[1].team_name = match->preceding_b->winner_team->name; @@ -2408,8 +2370,6 @@ void set_mask_for_ep3_game_command(void* vdata, size_t size, uint8_t mask_key) { header->mask_key = mask_key; } - - void send_quest_file_chunk( shared_ptr c, const string& filename, @@ -2433,7 +2393,7 @@ void send_quest_file_chunk( } void send_open_quest_file(shared_ptr c, const string& quest_name, - const string& basename, shared_ptr contents, QuestFileType type) { + const string& basename, shared_ptr contents, QuestFileType type) { switch (c->version()) { case GameVersion::DC: @@ -2463,7 +2423,7 @@ void send_open_quest_file(shared_ptr c, const string& quest_name, chunk_bytes = 0x400; } send_quest_file_chunk(c, basename.c_str(), offset / 0x400, - contents->data() + offset, chunk_bytes, (type != QuestFileType::ONLINE)); + contents->data() + offset, chunk_bytes, (type != QuestFileType::ONLINE)); } } else { c->sending_files.emplace(basename, contents); @@ -2534,7 +2494,7 @@ void send_card_auction_if_all_clients_ready( num_cards = s->ep3_card_auction_min_size; } else { num_cards = s->ep3_card_auction_min_size + - (random_object() % (s->ep3_card_auction_max_size - s->ep3_card_auction_min_size + 1)); + (random_object() % (s->ep3_card_auction_max_size - s->ep3_card_auction_min_size + 1)); } num_cards = min(num_cards, 0x14); @@ -2574,7 +2534,7 @@ void send_server_time(shared_ptr c) { string time_str(128, 0); size_t len = strftime(time_str.data(), time_str.size(), - "%Y:%m:%d: %H:%M:%S.000", &t_parsed); + "%Y:%m:%d: %H:%M:%S.000", &t_parsed); if (len == 0) { throw runtime_error("format_time buffer too short"); } diff --git a/src/SendCommands.hh b/src/SendCommands.hh index 0062b428..80283cf1 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -1,23 +1,21 @@ #pragma once #include -#include #include +#include #include #include #include #include "Client.hh" -#include "Lobby.hh" -#include "Server.hh" -#include "Menu.hh" -#include "Quest.hh" -#include "Text.hh" #include "CommandFormats.hh" #include "FunctionCompiler.hh" - - +#include "Lobby.hh" +#include "Menu.hh" +#include "Quest.hh" +#include "Server.hh" +#include "Text.hh" extern const std::unordered_set v2_crypt_initial_client_commands; extern const std::unordered_set v3_crypt_initial_client_commands; @@ -113,8 +111,6 @@ void send_command_t_vt(std::shared_ptr c, uint16_t command, void send_command_with_header(Channel& c, const void* data, size_t size); - - enum SendServerInitFlag { IS_INITIAL_CONNECTION = 0x01, USE_SECONDARY_MESSAGE = 0x02, diff --git a/src/Server.cc b/src/Server.cc index 2ae92b6c..8b465168 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -27,14 +27,14 @@ using namespace std; using namespace std::placeholders; - - void Server::disconnect_client(shared_ptr c) { if (c->channel.is_virtual_connection) { - server_log.info("Client disconnected: C-%" PRIX64 " on virtual connection %p", + server_log.info( + "Client disconnected: C-%" PRIX64 " on virtual connection %p", c->id, c->channel.bev.get()); } else { - server_log.info("Client disconnected: C-%" PRIX64 " on fd %d", + server_log.info( + "Client disconnected: C-%" PRIX64 " on fd %d", c->id, bufferevent_getfd(c->channel.bev.get())); } @@ -110,7 +110,7 @@ void Server::on_listen_accept(struct evconnlistener* listener, return; } - struct bufferevent *bev = bufferevent_socket_new(this->base.get(), fd, + struct bufferevent* bev = bufferevent_socket_new(this->base.get(), fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); shared_ptr c(new Client( bev, listening_socket->version, listening_socket->behavior)); @@ -140,7 +140,8 @@ void Server::connect_client( c->channel.on_error = Server::on_client_error; c->channel.context_obj = this; - server_log.info("Client connected: C-%" PRIX64 " on virtual connection %p via T-%hu-%s-%s-VI", + server_log.info( + "Client connected: C-%" PRIX64 " on virtual connection %p via T-%hu-%s-%s-VI", c->id, bev, server_port, @@ -211,9 +212,9 @@ void Server::on_client_error(Channel& ch, short events) { Server::Server( shared_ptr base, shared_ptr state) - : base(base), - destroy_clients_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &Server::dispatch_destroy_clients, this), event_free), - state(state) { } + : base(base), + destroy_clients_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &Server::dispatch_destroy_clients, this), event_free), + state(state) {} void Server::listen( const std::string& addr_str, @@ -243,12 +244,19 @@ void Server::listen(const std::string& addr_str, int port, GameVersion version, this->listen(addr_str, "", port, version, behavior); } -Server::ListeningSocket::ListeningSocket(Server* s, const std::string& addr_str, - int fd, GameVersion version, ServerBehavior behavior) : - addr_str(addr_str), fd(fd), version(version), behavior(behavior), listener( - evconnlistener_new(s->base.get(), Server::dispatch_on_listen_accept, s, - LEV_OPT_REUSEABLE, 0, this->fd), evconnlistener_free) { - evconnlistener_set_error_cb(this->listener.get(), +Server::ListeningSocket::ListeningSocket( + Server* s, const std::string& addr_str, + int fd, GameVersion version, ServerBehavior behavior) + : addr_str(addr_str), + fd(fd), + version(version), + behavior(behavior), + listener(evconnlistener_new( + s->base.get(), Server::dispatch_on_listen_accept, s, + LEV_OPT_REUSEABLE, 0, this->fd), + evconnlistener_free) { + evconnlistener_set_error_cb( + this->listener.get(), Server::dispatch_on_listen_error); } @@ -257,7 +265,8 @@ void Server::add_socket( int fd, GameVersion version, ServerBehavior behavior) { - this->listening_sockets.emplace(piecewise_construct, forward_as_tuple(fd), + this->listening_sockets.emplace( + piecewise_construct, forward_as_tuple(fd), forward_as_tuple(this, addr_str, fd, version, behavior)); } @@ -276,10 +285,12 @@ vector> Server::get_clients_by_identifier(const string& ident int64_t serial_number_dec = -1; try { serial_number_dec = stoul(ident, nullptr, 10); - } catch (const invalid_argument&) { } + } catch (const invalid_argument&) { + } try { serial_number_hex = stoul(ident, nullptr, 16); - } catch (const invalid_argument&) { } + } catch (const invalid_argument&) { + } u16string u16name = decode_sjis(ident); // TODO: It's kind of not great that we do a linear search here, but this is diff --git a/src/Server.hh b/src/Server.hh index 456f63b5..a97ef921 100644 --- a/src/Server.hh +++ b/src/Server.hh @@ -2,16 +2,14 @@ #include +#include +#include #include #include -#include -#include #include "Client.hh" #include "ServerState.hh" - - class Server { public: Server() = delete; @@ -44,7 +42,7 @@ private: int fd; GameVersion version; ServerBehavior behavior; - std::unique_ptr listener; + std::unique_ptr listener; ListeningSocket( Server* s, @@ -64,13 +62,13 @@ private: void destroy_clients(); static void dispatch_on_listen_accept(struct evconnlistener* listener, - evutil_socket_t fd, struct sockaddr *address, int socklen, void* ctx); + evutil_socket_t fd, struct sockaddr* address, int socklen, void* ctx); static void dispatch_on_listen_error(struct evconnlistener* listener, void* ctx); void disconnect_client(std::shared_ptr c); void on_listen_accept(struct evconnlistener* listener, evutil_socket_t fd, - struct sockaddr *address, int socklen); + struct sockaddr* address, int socklen); void on_listen_error(struct evconnlistener* listener); static void on_client_input(Channel& ch, uint16_t command, uint32_t flag, std::string& data); diff --git a/src/ServerShell.cc b/src/ServerShell.cc index ef32128b..fea8caae 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -4,22 +4,21 @@ #include #include -#include #include +#include #include "ReceiveCommands.hh" -#include "ServerState.hh" #include "SendCommands.hh" +#include "ServerState.hh" #include "StaticGameData.hh" using namespace std; - - ServerShell::ServerShell( shared_ptr base, shared_ptr state) - : Shell(base), state(state) { } + : Shell(base), + state(state) {} void ServerShell::print_prompt() { fwritex(stdout, Shell::PROMPT); @@ -254,9 +253,7 @@ same as the client\'s serial number). For example, to send a ping to the proxy\n session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ "); - - - // SERVER COMMANDS + // SERVER COMMANDS } else if (command_name == "reload") { auto types = split(command_args, ' '); @@ -577,9 +574,7 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ fprintf(stderr, "no such tournament exists\n"); } - - - // PROXY COMMANDS + // PROXY COMMANDS } else if ((command_name == "sc") || (command_name == "ss")) { string data = parse_data_string(command_args, nullptr, ParseDataFlags::ALLOW_FILES); @@ -591,7 +586,8 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ shared_ptr proxy_session; try { proxy_session = this->get_proxy_session(session_name); - } catch (const exception&) { } + } catch (const exception&) { + } if (proxy_session.get()) { if (command_name[1] == 's') { @@ -707,9 +703,7 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ } else { session->options.override_lobby_event = event_for_name(command_args); if ((session->version != GameVersion::DC) && - (session->version != GameVersion::PC) && ( - !((session->version == GameVersion::GC) && - (session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)))) { + (session->version != GameVersion::PC) && (!((session->version == GameVersion::GC) && (session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)))) { session->client_channel.send(0xDA, session->options.override_lobby_event); } } diff --git a/src/ServerShell.hh b/src/ServerShell.hh index 91834bff..e423c945 100644 --- a/src/ServerShell.hh +++ b/src/ServerShell.hh @@ -5,13 +5,11 @@ #include -#include "Shell.hh" #include "ProxyServer.hh" +#include "Shell.hh" #define SHELL_PROMPT "newserv> " - - class ServerShell : public Shell { public: ServerShell( diff --git a/src/ServerState.cc b/src/ServerState.cc index 5701f249..1abcb7c3 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -15,30 +15,28 @@ using namespace std; - - ServerState::ServerState(const char* config_filename, bool is_replay) - : config_filename(config_filename), - is_replay(is_replay), - dns_server_port(0), - ip_stack_debug(false), - allow_unregistered_users(false), - allow_saving(true), - item_tracking_enabled(true), - episode_3_send_function_call_enabled(false), - catch_handler_exceptions(true), - ep3_behavior_flags(0), - run_shell_behavior(RunShellBehavior::DEFAULT), - ep3_card_auction_points(0), - ep3_card_auction_min_size(0), - ep3_card_auction_max_size(0), - next_lobby_id(1), - pre_lobby_event(0), - ep3_menu_song(-1), - local_address(0), - external_address(0), - proxy_allow_save_files(true), - proxy_enable_login_options(false) { + : config_filename(config_filename), + is_replay(is_replay), + dns_server_port(0), + ip_stack_debug(false), + allow_unregistered_users(false), + allow_saving(true), + item_tracking_enabled(true), + episode_3_send_function_call_enabled(false), + catch_handler_exceptions(true), + ep3_behavior_flags(0), + run_shell_behavior(RunShellBehavior::DEFAULT), + ep3_card_auction_points(0), + ep3_card_auction_min_size(0), + ep3_card_auction_max_size(0), + next_lobby_id(1), + pre_lobby_event(0), + ep3_menu_song(-1), + local_address(0), + external_address(0), + proxy_allow_save_files(true), + proxy_enable_login_options(false) { vector> non_v1_only_lobbies; vector> ep3_only_lobbies; @@ -111,7 +109,8 @@ void ServerState::add_client_to_available_lobby(shared_ptr c) { l->add_client(c); added_to_lobby = l; } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } if (!added_to_lobby.get()) { @@ -126,7 +125,8 @@ void ServerState::add_client_to_available_lobby(shared_ptr c) { l->add_client(c); added_to_lobby = l; break; - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } } @@ -181,7 +181,7 @@ bool ServerState::change_client_lobby( } void ServerState::send_lobby_join_notifications(shared_ptr l, - shared_ptr joining_client) { + shared_ptr joining_client) { for (auto& other_client : l->clients) { if (!other_client) { continue; @@ -259,19 +259,21 @@ void ServerState::remove_lobby(uint32_t lobby_id) { } shared_ptr ServerState::find_client(const std::u16string* identifier, - uint64_t serial_number, shared_ptr l) { + uint64_t serial_number, shared_ptr l) { if ((serial_number == 0) && identifier) { try { serial_number = stoull(encode_sjis(*identifier), nullptr, 0); - } catch (const exception&) { } + } catch (const exception&) { + } } // look in the current lobby first if (l) { try { return l->find_client(identifier, serial_number); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } // look in all lobbies if not found @@ -281,7 +283,8 @@ shared_ptr ServerState::find_client(const std::u16string* identifier, } try { return other_l->find_client(identifier, serial_number); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } throw out_of_range("client not found"); @@ -306,8 +309,6 @@ uint32_t ServerState::connect_address_for_client(std::shared_ptr c) { } } - - shared_ptr> ServerState::information_menu_for_version(GameVersion version) { if ((version == GameVersion::DC) || (version == GameVersion::PC)) { return this->information_menu_v2; @@ -347,8 +348,6 @@ const vector>& ServerState::proxy_destinations_for_versio } } - - void ServerState::set_port_configuration( const vector& port_configs) { this->name_to_port_config.clear(); @@ -383,8 +382,6 @@ void ServerState::set_port_configuration( } } - - void ServerState::create_menus(shared_ptr config_json) { config_log.info("Creating menus"); const auto& d = config_json->as_dict(); @@ -400,15 +397,15 @@ void ServerState::create_menus(shared_ptr config_json) { shared_ptr> information_contents(new vector()); information_menu_v3->emplace_back(InformationMenuItemID::GO_BACK, u"Go back", - u"Return to the\nmain menu", 0); + u"Return to the\nmain menu", 0); { uint32_t item_id = 0; for (const auto& item : d.at("InformationMenuContents")->as_list()) { auto& v = item->as_list(); information_menu_v2->emplace_back(item_id, decode_sjis(v.at(0)->as_string()), - decode_sjis(v.at(1)->as_string()), 0); + decode_sjis(v.at(1)->as_string()), 0); information_menu_v3->emplace_back(item_id, decode_sjis(v.at(0)->as_string()), - decode_sjis(v.at(1)->as_string()), MenuItem::Flag::REQUIRES_MESSAGE_BOXES); + decode_sjis(v.at(1)->as_string()), MenuItem::Flag::REQUIRES_MESSAGE_BOXES); information_contents->emplace_back(decode_sjis(v.at(2)->as_string())); item_id++; } @@ -418,9 +415,9 @@ void ServerState::create_menus(shared_ptr config_json) { this->information_contents = information_contents; auto generate_proxy_destinations_menu = [&]( - vector& ret_menu, - vector>& ret_pds, - const char* key) { + vector& ret_menu, + vector>& ret_pds, + const char* key) { try { map> sorted_jsons; for (const auto& it : d.at(key)->as_dict()) { @@ -431,20 +428,21 @@ void ServerState::create_menus(shared_ptr config_json) { ret_pds.clear(); ret_menu.emplace_back(ProxyDestinationsMenuItemID::GO_BACK, u"Go back", - u"Return to the\nmain menu", 0); + u"Return to the\nmain menu", 0); ret_menu.emplace_back(ProxyDestinationsMenuItemID::OPTIONS, u"Options", - u"Set proxy options", 0); + u"Set proxy options", 0); uint32_t item_id = 0; for (const auto& item : sorted_jsons) { const string& netloc_str = item.second->as_string(); const string& description = "$C7Remote server:\n$C6" + netloc_str; ret_menu.emplace_back(item_id, decode_sjis(item.first), - decode_sjis(description), 0); + decode_sjis(description), 0); ret_pds.emplace_back(parse_netloc(netloc_str)); item_id++; } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } }; generate_proxy_destinations_menu( @@ -492,9 +490,9 @@ void ServerState::create_menus(shared_ptr config_json) { } this->main_menu.emplace_back(MainMenuItemID::GO_TO_LOBBY, u"Go to lobby", - u"Join the lobby", 0); + u"Join the lobby", 0); this->main_menu.emplace_back(MainMenuItemID::INFORMATION, u"Information", - u"View server\ninformation", MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::REQUIRES_MESSAGE_BOXES); + u"View server\ninformation", MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::REQUIRES_MESSAGE_BOXES); uint32_t proxy_destinations_menu_item_flags = // DCNTE doesn't support multiple ship select menus without changing // servers (via a 19 command) apparently :( @@ -505,38 +503,39 @@ void ServerState::create_menus(shared_ptr config_json) { (this->proxy_destinations_xb.empty() ? MenuItem::Flag::INVISIBLE_ON_XB : 0) | MenuItem::Flag::INVISIBLE_ON_BB; this->main_menu.emplace_back(MainMenuItemID::PROXY_DESTINATIONS, u"Proxy server", - u"Connect to another\nserver", proxy_destinations_menu_item_flags); + u"Connect to another\nserver", proxy_destinations_menu_item_flags); this->main_menu.emplace_back(MainMenuItemID::DOWNLOAD_QUESTS, u"Download quests", - u"Download quests", MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_BB); + u"Download quests", MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_BB); if (!this->is_replay) { if (!this->function_code_index->patch_menu_empty()) { this->main_menu.emplace_back(MainMenuItemID::PATCHES, u"Patches", - u"Change game\nbehaviors", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL); + u"Change game\nbehaviors", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL); } if (!this->dol_file_index->empty()) { this->main_menu.emplace_back(MainMenuItemID::PROGRAMS, u"Programs", - u"Run GameCube\nprograms", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL | MenuItem::Flag::REQUIRES_SAVE_DISABLED); + u"Run GameCube\nprograms", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL | MenuItem::Flag::REQUIRES_SAVE_DISABLED); } } this->main_menu.emplace_back(MainMenuItemID::DISCONNECT, u"Disconnect", - u"Disconnect", 0); + u"Disconnect", 0); this->main_menu.emplace_back(MainMenuItemID::CLEAR_LICENSE, u"Clear license", - u"Disconnect with an\ninvalid license error\nso you can enter a\ndifferent serial\nnumber, access key,\nor password", - MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_BB); + u"Disconnect with an\ninvalid license error\nso you can enter a\ndifferent serial\nnumber, access key,\nor password", + MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_BB); try { this->welcome_message = decode_sjis(d.at("WelcomeMessage")->as_string()); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { this->pc_patch_server_message = decode_sjis(d.at("PCPatchServerMessage")->as_string()); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { this->bb_patch_server_message = decode_sjis(d.at("BBPatchServerMessage")->as_string()); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } - - shared_ptr ServerState::load_bb_file( const std::string& patch_index_filename, const std::string& gsl_filename, @@ -595,8 +594,6 @@ shared_ptr ServerState::load_bb_file( } } - - void ServerState::collect_network_addresses() { config_log.info("Reading network addresses"); this->all_addresses = get_local_addresses(); @@ -640,7 +637,8 @@ void ServerState::parse_config(shared_ptr config_json) { } this->username = user_from_env; } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } this->set_port_configuration(parse_port_configuration(d.at("PortConfiguration"))); @@ -649,7 +647,7 @@ void ServerState::parse_config(shared_ptr config_json) { this->local_address = this->all_addresses.at(local_address_str); string addr_str = string_for_address(this->local_address); config_log.info("Added local address: %s (%s)", addr_str.c_str(), - local_address_str.c_str()); + local_address_str.c_str()); } catch (const out_of_range&) { this->local_address = address_for_string(local_address_str.c_str()); config_log.info("Added local address: %s", local_address_str.c_str()); @@ -661,7 +659,7 @@ void ServerState::parse_config(shared_ptr config_json) { this->external_address = this->all_addresses.at(external_address_str); string addr_str = string_for_address(this->external_address); config_log.info("Added external address: %s (%s)", addr_str.c_str(), - external_address_str.c_str()); + external_address_str.c_str()); } catch (const out_of_range&) { this->external_address = address_for_string(external_address_str.c_str()); config_log.info("Added external address: %s", external_address_str.c_str()); @@ -678,10 +676,12 @@ void ServerState::parse_config(shared_ptr config_json) { for (const auto& item : d.at("IPStackListen")->as_list()) { this->ip_stack_addresses.emplace_back(item->as_string()); } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { this->ip_stack_debug = d.at("IPStackDebug")->as_bool(); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { this->allow_unregistered_users = d.at("AllowUnregisteredUsers")->as_bool(); @@ -748,14 +748,16 @@ void ServerState::parse_config(shared_ptr config_json) { const auto& card_name = it.first; const auto& card_cfg_json = it.second->as_list(); this->ep3_card_auction_pool.emplace(card_name, make_pair( - card_cfg_json.at(0)->as_int(), card_cfg_json.at(1)->as_int())); + card_cfg_json.at(0)->as_int(), card_cfg_json.at(1)->as_int())); } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } shared_ptr log_levels_json; try { log_levels_json = d.at("LogLevels"); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } if (log_levels_json.get()) { set_log_levels_from_json(log_levels_json); } @@ -772,10 +774,9 @@ void ServerState::parse_config(shared_ptr config_json) { try { bool run_shell = d.at("RunInteractiveShell")->as_bool(); - this->run_shell_behavior = run_shell ? - ServerState::RunShellBehavior::ALWAYS : - ServerState::RunShellBehavior::NEVER; - } catch (const out_of_range&) { } + this->run_shell_behavior = run_shell ? ServerState::RunShellBehavior::ALWAYS : ServerState::RunShellBehavior::NEVER; + } catch (const out_of_range&) { + } try { auto v = d.at("LobbyEvent"); @@ -784,11 +785,13 @@ void ServerState::parse_config(shared_ptr config_json) { for (const auto& l : this->all_lobbies()) { l->event = event; } - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { this->ep3_menu_song = d.at("Episode3MenuSong")->as_int(); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } } void ServerState::load_licenses() { @@ -860,10 +863,10 @@ void ServerState::load_item_tables() { this->tool_random_set.reset(new ToolRandomSet(tool_data)); const char* filenames[4] = { - "system/blueburst/WeaponRandomNormal_GC.rel", - "system/blueburst/WeaponRandomHard_GC.rel", - "system/blueburst/WeaponRandomVeryHard_GC.rel", - "system/blueburst/WeaponRandomUltimate_GC.rel", + "system/blueburst/WeaponRandomNormal_GC.rel", + "system/blueburst/WeaponRandomHard_GC.rel", + "system/blueburst/WeaponRandomVeryHard_GC.rel", + "system/blueburst/WeaponRandomUltimate_GC.rel", }; for (size_t z = 0; z < 4; z++) { shared_ptr weapon_data(new string(load_file(filenames[z]))); diff --git a/src/ServerState.hh b/src/ServerState.hh index 2a758cc8..cebd3db4 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -9,21 +9,19 @@ #include #include +#include "Client.hh" +#include "CommonItemSet.hh" #include "Episode3/DataIndex.hh" #include "Episode3/Tournament.hh" -#include "Client.hh" #include "FunctionCompiler.hh" #include "GSLArchive.hh" +#include "ItemParameterTable.hh" #include "Items.hh" #include "LevelTable.hh" #include "License.hh" #include "Lobby.hh" #include "Menu.hh" #include "Quest.hh" -#include "CommonItemSet.hh" -#include "ItemParameterTable.hh" - - // Forward declarations due to reference cycles class ProxyServer; @@ -121,7 +119,6 @@ struct ServerState { std::shared_ptr proxy_server; std::shared_ptr game_server; - std::shared_ptr client_options_cache; ServerState(const char* config_filename, bool is_replay); @@ -143,9 +140,9 @@ struct ServerState { void remove_lobby(uint32_t lobby_id); std::shared_ptr find_client( - const std::u16string* identifier = nullptr, - uint64_t serial_number = 0, - std::shared_ptr l = nullptr); + 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); @@ -154,7 +151,7 @@ struct ServerState { const std::vector>& proxy_destinations_for_version(GameVersion version); void set_port_configuration( - const std::vector& port_configs); + const std::vector& port_configs); std::shared_ptr load_bb_file( const std::string& patch_index_filename, diff --git a/src/Shell.cc b/src/Shell.cc index 8f9d78e1..e9a2217e 100644 --- a/src/Shell.cc +++ b/src/Shell.cc @@ -8,26 +8,22 @@ using namespace std; - - const std::string Shell::PROMPT("newserv> "); - - -Shell::exit_shell::exit_shell() : runtime_error("shell exited") { } - - +Shell::exit_shell::exit_shell() : runtime_error("shell exited") {} Shell::Shell(std::shared_ptr base) - : base(base), - read_event(event_new(this->base.get(), 0, EV_READ | EV_PERSIST, - &Shell::dispatch_read_stdin, this), event_free), - prompt_event(event_new(this->base.get(), 0, EV_TIMEOUT, - &Shell::dispatch_print_prompt, this), event_free) { + : base(base), + read_event( + event_new(this->base.get(), 0, EV_READ | EV_PERSIST, &Shell::dispatch_read_stdin, this), + event_free), + prompt_event( + event_new(this->base.get(), 0, EV_TIMEOUT, &Shell::dispatch_print_prompt, this), + event_free) { event_add(this->read_event.get(), nullptr); // Schedule an event to print the prompt as soon as the event loop starts - // running. we do this so the prompt appears after any initialization + // running. We do this so the prompt appears after any initialization // messages that come after starting the shell struct timeval tv = {0, 0}; event_add(this->prompt_event.get(), &tv); @@ -40,7 +36,7 @@ void Shell::dispatch_print_prompt(evutil_socket_t, short, void* ctx) { } void Shell::print_prompt() { - // default behavior: no prompt + // Default behavior: no prompt } void Shell::dispatch_read_stdin(evutil_socket_t, short, void* ctx) { @@ -54,7 +50,8 @@ void Shell::read_stdin() { short fd_events = 0; try { fd_events = poll_result.at(0); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } if (!(fd_events & POLLIN)) { break; diff --git a/src/Shell.hh b/src/Shell.hh index a21e9f6a..8202bf8d 100644 --- a/src/Shell.hh +++ b/src/Shell.hh @@ -2,15 +2,13 @@ #include -#include #include -#include #include +#include +#include #include "ServerState.hh" - - class Shell { public: Shell(std::shared_ptr base); diff --git a/src/StaticGameData.cc b/src/StaticGameData.cc index 5a9fe16e..f9e3b3e0 100644 --- a/src/StaticGameData.cc +++ b/src/StaticGameData.cc @@ -4,17 +4,13 @@ using namespace std; - - size_t area_limit_for_episode(Episode ep) { switch (ep) { case Episode::EP1: case Episode::EP2: return 17; - break; case Episode::EP4: return 10; - break; default: return 0; } @@ -58,8 +54,6 @@ const char* abbreviation_for_episode(Episode ep) { } } - - const char* name_for_mode(GameMode mode) { switch (mode) { case GameMode::NORMAL: @@ -90,130 +84,121 @@ const char* abbreviation_for_mode(GameMode mode) { } } - - -const vector section_id_to_name({ - "Viridia", "Greennill", "Skyly", "Bluefull", "Purplenum", "Pinkal", "Redria", - "Oran", "Yellowboze", "Whitill"}); +const vector section_id_to_name = { + "Viridia", "Greennill", "Skyly", "Bluefull", "Purplenum", + "Pinkal", "Redria", "Oran", "Yellowboze", "Whitill"}; const unordered_map name_to_section_id({ - {"viridia", 0}, - {"greennill", 1}, - {"skyly", 2}, - {"bluefull", 3}, - {"purplenum", 4}, - {"pinkal", 5}, - {"redria", 6}, - {"oran", 7}, - {"yellowboze", 8}, - {"whitill", 9}, + {"viridia", 0}, + {"greennill", 1}, + {"skyly", 2}, + {"bluefull", 3}, + {"purplenum", 4}, + {"pinkal", 5}, + {"redria", 6}, + {"oran", 7}, + {"yellowboze", 8}, + {"whitill", 9}, - // Shortcuts for chat commands - {"b", 3}, - {"g", 1}, - {"o", 7}, - {"pi", 5}, - {"pu", 4}, - {"r", 6}, - {"s", 2}, - {"v", 0}, - {"w", 9}, - {"y", 8}, + // Shortcuts for chat commands + {"b", 3}, + {"g", 1}, + {"o", 7}, + {"pi", 5}, + {"pu", 4}, + {"r", 6}, + {"s", 2}, + {"v", 0}, + {"w", 9}, + {"y", 8}, }); -const vector lobby_event_to_name({ - "none", "xmas", "none", "val", "easter", "hallo", "sonic", "newyear", - "summer", "white", "wedding", "fall", "s-spring", "s-summer", "spring"}); +const vector lobby_event_to_name = { + "none", "xmas", "none", "val", "easter", "hallo", "sonic", "newyear", + "summer", "white", "wedding", "fall", "s-spring", "s-summer", "spring"}; const unordered_map name_to_lobby_event({ - {"none", 0}, - {"xmas", 1}, - {"val", 3}, - {"easter", 4}, - {"hallo", 5}, - {"sonic", 6}, - {"newyear", 7}, - {"summer", 8}, - {"white", 9}, - {"wedding", 10}, - {"fall", 11}, - {"s-spring", 12}, - {"s-summer", 13}, - {"spring", 14}, + {"none", 0}, + {"xmas", 1}, + {"val", 3}, + {"easter", 4}, + {"hallo", 5}, + {"sonic", 6}, + {"newyear", 7}, + {"summer", 8}, + {"white", 9}, + {"wedding", 10}, + {"fall", 11}, + {"s-spring", 12}, + {"s-summer", 13}, + {"spring", 14}, }); const unordered_map lobby_type_to_name({ - {0x00, "normal"}, - {0x0F, "inormal"}, - {0x10, "ipc"}, - {0x11, "iball"}, - {0x67, "cave2u"}, - {0xD4, "cave1"}, - {0xE9, "planet"}, - {0xEA, "clouds"}, - {0xED, "cave"}, - {0xEE, "jungle"}, - {0xEF, "forest2-2"}, - {0xF0, "forest2-1"}, - {0xF1, "windpower"}, - {0xF2, "overview"}, - {0xF3, "seaside"}, - {0xF4, "some?"}, - {0xF5, "dmorgue"}, - {0xF6, "caelum"}, - {0xF8, "digital"}, - {0xF9, "boss1"}, - {0xFA, "boss2"}, - {0xFB, "boss3"}, - {0xFC, "dragon"}, - {0xFD, "derolle"}, - {0xFE, "volopt"}, - {0xFF, "darkfalz"}, + {0x00, "normal"}, + {0x0F, "inormal"}, + {0x10, "ipc"}, + {0x11, "iball"}, + {0x67, "cave2u"}, + {0xD4, "cave1"}, + {0xE9, "planet"}, + {0xEA, "clouds"}, + {0xED, "cave"}, + {0xEE, "jungle"}, + {0xEF, "forest2-2"}, + {0xF0, "forest2-1"}, + {0xF1, "windpower"}, + {0xF2, "overview"}, + {0xF3, "seaside"}, + {0xF4, "some?"}, + {0xF5, "dmorgue"}, + {0xF6, "caelum"}, + {0xF8, "digital"}, + {0xF9, "boss1"}, + {0xFA, "boss2"}, + {0xFB, "boss3"}, + {0xFC, "dragon"}, + {0xFD, "derolle"}, + {0xFE, "volopt"}, + {0xFF, "darkfalz"}, }); const unordered_map name_to_lobby_type({ - {"normal", 0x00}, - {"inormal", 0x0F}, - {"ipc", 0x10}, - {"iball", 0x11}, - {"cave1", 0xD4}, - {"cave2u", 0x67}, - {"dragon", 0xFC}, - {"derolle", 0xFD}, - {"volopt", 0xFE}, - {"darkfalz", 0xFF}, - {"planet", 0xE9}, - {"clouds", 0xEA}, - {"cave", 0xED}, - {"jungle", 0xEE}, - {"forest2-2", 0xEF}, - {"forest2-1", 0xF0}, - {"windpower", 0xF1}, - {"overview", 0xF2}, - {"seaside", 0xF3}, - {"some?", 0xF4}, - {"dmorgue", 0xF5}, - {"caelum", 0xF6}, - {"digital", 0xF8}, - {"boss1", 0xF9}, - {"boss2", 0xFA}, - {"boss3", 0xFB}, - {"knight", 0xFC}, - {"sky", 0xFE}, - {"morgue", 0xFF}, + {"normal", 0x00}, + {"inormal", 0x0F}, + {"ipc", 0x10}, + {"iball", 0x11}, + {"cave1", 0xD4}, + {"cave2u", 0x67}, + {"dragon", 0xFC}, + {"derolle", 0xFD}, + {"volopt", 0xFE}, + {"darkfalz", 0xFF}, + {"planet", 0xE9}, + {"clouds", 0xEA}, + {"cave", 0xED}, + {"jungle", 0xEE}, + {"forest2-2", 0xEF}, + {"forest2-1", 0xF0}, + {"windpower", 0xF1}, + {"overview", 0xF2}, + {"seaside", 0xF3}, + {"some?", 0xF4}, + {"dmorgue", 0xF5}, + {"caelum", 0xF6}, + {"digital", 0xF8}, + {"boss1", 0xF9}, + {"boss2", 0xFA}, + {"boss3", 0xFB}, + {"knight", 0xFC}, + {"sky", 0xFE}, + {"morgue", 0xFF}, }); -const vector npc_id_to_name({ - "ninja", "rico", "sonic", "knuckles", "tails", "flowen", "elly"}); +const vector npc_id_to_name({"ninja", "rico", "sonic", "knuckles", "tails", "flowen", "elly"}); -const unordered_map name_to_npc_id({ - {"ninja", 0}, - {"rico", 1}, - {"sonic", 2}, - {"knuckles", 3}, - {"tails", 4}, - {"flowen", 5}, - {"elly", 6}}); +const unordered_map name_to_npc_id = { + {"ninja", 0}, {"rico", 1}, {"sonic", 2}, {"knuckles", 3}, {"tails", 4}, {"flowen", 5}, {"elly", 6}}; const string& name_for_section_id(uint8_t section_id) { if (section_id < section_id_to_name.size()) { @@ -232,14 +217,16 @@ uint8_t section_id_for_name(const string& name) { string lower_name = tolower(name); try { return name_to_section_id.at(lower_name); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { uint64_t x = stoul(name); if (x < section_id_to_name.size()) { return x; } } catch (const invalid_argument&) { - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } return 0xFF; } @@ -263,14 +250,16 @@ u16string u16name_for_event(uint8_t event) { uint8_t event_for_name(const string& name) { try { return name_to_lobby_event.at(name); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { uint64_t x = stoul(name); if (x < lobby_event_to_name.size()) { return x; } } catch (const invalid_argument&) { - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } return 0xFF; } @@ -294,14 +283,16 @@ u16string u16name_for_lobby_type(uint8_t type) { uint8_t lobby_type_for_name(const string& name) { try { return name_to_lobby_type.at(name); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { uint64_t x = stoul(name); if (x < lobby_type_to_name.size()) { return x; } } catch (const invalid_argument&) { - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } return 0x80; } @@ -325,14 +316,16 @@ u16string u16name_for_npc(uint8_t npc) { uint8_t npc_for_name(const string& name) { try { return name_to_npc_id.at(name); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { uint64_t x = stoul(name); if (x < npc_id_to_name.size()) { return x; } } catch (const invalid_argument&) { - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } return 0xFF; } @@ -340,22 +333,20 @@ uint8_t npc_for_name(const u16string& name) { return npc_for_name(encode_sjis(name)); } - - const char* name_for_char_class(uint8_t cls) { static const array names = { - "HUmar", - "HUnewearl", - "HUcast", - "RAmar", - "RAcast", - "RAcaseal", - "FOmarl", - "FOnewm", - "FOnewearl", - "HUcaseal", - "FOmar", - "RAmarl", + "HUmar", + "HUnewearl", + "HUcast", + "RAmar", + "RAcast", + "RAcaseal", + "FOmarl", + "FOnewm", + "FOnewearl", + "HUcaseal", + "FOmar", + "RAmarl", }; try { return names.at(cls); @@ -366,18 +357,18 @@ const char* name_for_char_class(uint8_t cls) { const char* abbreviation_for_char_class(uint8_t cls) { static const array names = { - "HUmr", - "HUnl", - "HUcs", - "RAmr", - "RAcs", - "RAcl", - "FOml", - "FOnm", - "FOnl", - "HUcl", - "FOmr", - "RAml", + "HUmr", + "HUnl", + "HUcs", + "RAmr", + "RAcs", + "RAcl", + "FOml", + "FOnm", + "FOnl", + "HUcl", + "FOmr", + "RAml", }; try { return names.at(cls); @@ -386,14 +377,12 @@ const char* abbreviation_for_char_class(uint8_t cls) { } } - - const char* name_for_difficulty(uint8_t difficulty) { static const array names = { - "Normal", - "Hard", - "Very Hard", - "Ultimate", + "Normal", + "Hard", + "Very Hard", + "Ultimate", }; try { return names.at(difficulty); @@ -411,8 +400,6 @@ char abbreviation_for_difficulty(uint8_t difficulty) { } } - - char char_for_language_code(uint8_t language) { switch (language) { case 0: @@ -430,8 +417,6 @@ char char_for_language_code(uint8_t language) { } } - - size_t max_stack_size_for_item(uint8_t data0, uint8_t data1) { if (data0 == 4) { return 999999; @@ -446,35 +431,33 @@ size_t max_stack_size_for_item(uint8_t data0, uint8_t data1) { return 1; } - - -const vector tech_id_to_name({ - "foie", "gifoie", "rafoie", - "barta", "gibarta", "rabarta", - "zonde", "gizonde", "razonde", - "grants", "deband", "jellen", "zalure", "shifta", - "ryuker", "resta", "anti", "reverser", "megid"}); +const vector tech_id_to_name = { + "foie", "gifoie", "rafoie", + "barta", "gibarta", "rabarta", + "zonde", "gizonde", "razonde", + "grants", "deband", "jellen", "zalure", "shifta", + "ryuker", "resta", "anti", "reverser", "megid"}; const unordered_map name_to_tech_id({ - {"foie", 0}, - {"gifoie", 1}, - {"rafoie", 2}, - {"barta", 3}, - {"gibarta", 4}, - {"rabarta", 5}, - {"zonde", 6}, - {"gizonde", 7}, - {"razonde", 8}, - {"grants", 9}, - {"deband", 10}, - {"jellen", 11}, - {"zalure", 12}, - {"shifta", 13}, - {"ryuker", 14}, - {"resta", 15}, - {"anti", 16}, - {"reverser", 17}, - {"megid", 18}, + {"foie", 0}, + {"gifoie", 1}, + {"rafoie", 2}, + {"barta", 3}, + {"gibarta", 4}, + {"rabarta", 5}, + {"zonde", 6}, + {"gizonde", 7}, + {"razonde", 8}, + {"grants", 9}, + {"deband", 10}, + {"jellen", 11}, + {"zalure", 12}, + {"shifta", 13}, + {"ryuker", 14}, + {"resta", 15}, + {"anti", 16}, + {"reverser", 17}, + {"megid", 18}, }); const string& name_for_technique(uint8_t tech) { @@ -493,14 +476,16 @@ u16string u16name_for_technique(uint8_t tech) { uint8_t technique_for_name(const string& name) { try { return name_to_tech_id.at(name); - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } try { uint64_t x = stoul(name); if (x < tech_id_to_name.size()) { return x; } } catch (const invalid_argument&) { - } catch (const out_of_range&) { } + } catch (const out_of_range&) { + } return 0xFF; } diff --git a/src/StaticGameData.hh b/src/StaticGameData.hh index d183531e..35e220dd 100644 --- a/src/StaticGameData.hh +++ b/src/StaticGameData.hh @@ -7,8 +7,6 @@ #include "FileContentsCache.hh" #include "Player.hh" - - enum class Episode { NONE = 0, EP1 = 1, @@ -32,8 +30,6 @@ enum class GameMode { const char* name_for_mode(GameMode mode); const char* abbreviation_for_mode(GameMode mode); - - size_t max_stack_size_for_item(uint8_t data0, uint8_t data1); extern const vector tech_id_to_name; diff --git a/src/Text.cc b/src/Text.cc index f0330085..4f85d0b0 100644 --- a/src/Text.cc +++ b/src/Text.cc @@ -1,18 +1,16 @@ #include "Text.hh" #include -#include #include #include +#include -#include #include #include +#include using namespace std; - - int char16ncmp(const char16_t* s1, const char16_t* s2, size_t count) { size_t x; for (x = 0; x < count && s1[x] != 0 && s2[x] != 0; x++) { @@ -30,8 +28,6 @@ int char16ncmp(const char16_t* s1, const char16_t* s2, size_t count) { return 0; } - - static vector unicode_to_sjis_table_data; static vector sjis_to_unicode_table_data; @@ -69,8 +65,6 @@ static const vector& unicode_to_sjis_table() { return unicode_to_sjis_table_data; } - - std::string encode_sjis(const char16_t* src, size_t src_count) { const auto& table = unicode_to_sjis_table(); diff --git a/src/Text.hh b/src/Text.hh index 2c24fc98..0718c59f 100644 --- a/src/Text.hh +++ b/src/Text.hh @@ -4,12 +4,10 @@ #include #include -#include -#include #include #include - - +#include +#include // (1a) Conversion functions @@ -49,14 +47,16 @@ inline const std::u16string& decode_sjis(const std::u16string& s) { return s; } template size_t text_strlen_t(const T* s) { size_t ret = 0; - for (; s[ret] != 0; ret++) { } + for (; s[ret] != 0; ret++) { + } return ret; } template size_t text_strnlen_t(const T* s, size_t count) { size_t ret = 0; - for (; (ret < count) && (s[ret] != 0); ret++) { } + for (; (ret < count) && (s[ret] != 0); ret++) { + } return ret; } @@ -113,8 +113,6 @@ size_t text_strnzcpy_t(T* dest, const T* src, size_t count) { return x; } - - // (2) Type conversion functions template @@ -183,8 +181,6 @@ inline size_t text_strnzcpy_t( return text_strnzcpy_t(dest, src, count); } - - // (3) Packed text objects for use in protocol structs template @@ -203,7 +199,7 @@ struct parray { this->clear(nullptr); } template ::value && !std::is_pointer::value, bool> = true> - parray() { } + parray() {} parray(const parray& other) { this->operator=(other); @@ -358,7 +354,6 @@ struct parray { } } __attribute__((packed)); - // TODO: It appears that these actually do not have to be null-terminated in PSO // commands some of the time. As an example, creating a game with a name with // the maximum length results in a C1 command with no null byte between the game @@ -370,7 +365,7 @@ struct ptext : parray { ptext() { this->clear(0); } - ptext(const ptext& other) : parray(other) { } + ptext(const ptext& other) : parray(other) {} ptext(ptext&& s) = delete; template @@ -496,8 +491,6 @@ struct ptext : parray { } } __attribute__((packed)); - - // (4) Markers and character replacement template diff --git a/src/Version.cc b/src/Version.cc index 47aa8455..77a8d687 100644 --- a/src/Version.cc +++ b/src/Version.cc @@ -8,14 +8,12 @@ using namespace std; - - -const vector version_to_login_port_name({ - "bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"}); -const vector version_to_lobby_port_name({ - "bb-patch", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); -const vector version_to_proxy_port_name({ - "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}); +const vector version_to_login_port_name = { + "bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"}; +const vector version_to_lobby_port_name = { + "bb-patch", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}; +const vector version_to_proxy_port_name = { + "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}; uint16_t flags_for_version(GameVersion version, int64_t sub_version) { switch (sub_version) { @@ -40,8 +38,8 @@ uint16_t flags_for_version(GameVersion version, int64_t sub_version) { // TODO: Which other sub_versions of DC v1 and v2 exist? case 0x20: // DCNTE - // In the case of DCNTE, the IS_TRIAL_EDITION flag is already set when we - // get here, so the remaining flags are the same as DCv1 + // In the case of DCNTE, the IS_TRIAL_EDITION flag is already set when we + // get here, so the remaining flags are the same as DCv1 case 0x21: // DCv1 US return Client::Flag::IS_DC_V1 | Client::Flag::NO_D6 | @@ -118,7 +116,7 @@ GameVersion version_for_name(const char* name) { } else if (!strcasecmp(name, "XB") || !strcasecmp(name, "Xbox")) { return GameVersion::XB; } else if (!strcasecmp(name, "BB") || !strcasecmp(name, "BlueBurst") || - !strcasecmp(name, "Blue Burst")) { + !strcasecmp(name, "Blue Burst")) { return GameVersion::BB; } else if (!strcasecmp(name, "Patch")) { return GameVersion::PATCH; diff --git a/src/Version.hh b/src/Version.hh index 307a5300..8fb49cd7 100644 --- a/src/Version.hh +++ b/src/Version.hh @@ -2,10 +2,8 @@ #include -#include #include - - +#include enum class GameVersion { PATCH = 0,